In-Place Editing

Việc chỉnh sửa một trường giá trị của một đối tượng đã là công việc quá quen thuộc với các lập trình viên nói chung, và ruby developer nói riêng.

Công việc thật đơn giản khi bạn chỉ cần click vào link edit và thay đổi các giá trị của trường muốn thay đổi, sau đó Submit, thế là xong. Quá dễ phải không? Nhưng thật nhàm chán và có phần bất tiện. Việc phải link đến một trang mới và Submit làm bạn cảm thấy thật mất thời gian! Tại sao không làm luôn chức năng sửa luôn trên trang hiển thị mà không cần phải link page, submit rồi load page này nọ nhỉ?

Hôm nay tôi sẽ giới thiệu đến bạn một công cụ hỗ trợ bạn giải quyết vấn đề trên, công cụ giúp ta có thể sửa thông tin một cách nhanh chóng và hiệu quả.

Giả sử ta có trang profile của người dùng như sau:

alt

và bây giờ tôi, muốn sửa trường Name và Email của từ profile của người dùng đó. Tôi sẽ dùng gem best_in_place.

Best in place

Với trang demo là trang user profile chúng ta sẽ thử thực hiện chức năng edit bằng cách sử dụng best_in_place.

Bước 1: add gem gem 'jquery-rails'gem 'best_in_place' vào Gemfile.

gem 'jquery-rails'
gem 'best_in_place'

Bước 2: include thư viện js vào project:

//= require jquery
//= require jquery_ujs
//= require jquery.purr
//= require best_in_place
//= require_tree .

ở đây, ta cần include require jquery.purr.

Bước 3: add vào đoạn coffee/js script của hàm best_in_place() vào project:

jQuery ->
  $('.best_in_place').best_in_place()

với class css .best_in_place ta sẽ định nghĩa trong view dưới đây.

Bước 4: thêm class và sử dụng best_in_place trong views.

từ đoạn code thuần views ban đầu của chúng ta như thế này ( chúng ta chỉ có thể xem )

<h1>User Profile</h1>

<p>
  <b>Name:</b>
  <%= @user.name %>
</p>
<p>
  <b>Email:</b>
  <%= @user.email %>
</p>
<p>
  <b>Gender:</b>
  <%= @user.gender %>
</p>
<p>
  <b>Public profile:</b>
  <%= @user.public_profile %>
</p>
<p>
  <%= @user.bio %>
</p>

<%= link_to 'Edit Profile', edit_user_path(@user) %>

Ta sẽ thay thế bằng đoạn code sử dụng best_in_place của các trường email và name:

<p>
  <b>Name:</b>
  <%= best_in_place @user, :name %>
</p>
<p>
  <b>Email:</b>
  <%= best_in_place @user, :email %>
</p>

Bước 5: Hoàn tất cài đặt gem và sử dụng thư viện js best_in_place

  • chạy bundle để cài gem
  • restart lại server là load lại trang.

Ta đã có thể edit được 2 trường mà ta vừa config nameemail như hình dưới:

alt

Bước 6: Lưu dữ liệu

Thay đổi trường giá trị và reload lại trang, dữ liệu mới được lưu vào database. Đến đây, đã cơ bản đạt được mục đích là thay đổi giá trị của trường, tuy nhiên bất tiện là ta phải load lại trang. Hmm.

alt

Bước tiếp theo, để cho hoàn thiện hơn khi không phải reload lại trang, và dùng hết tính năng mà best_in_place hỗ trợ, ta thêm vào controller:

class UsersController < ApplicationController
  respond_to :html, :json

  # Other actions omitted.

  def update
    @user = User.find(params[:id])
    @user.update_attributes(params[:user])
    respond_with @user
  end

end

Chúng ta vừa sử dụng truyền biến @user dạng JSON để có thể thay đổi bằng cách ấn Enter hoặc click con trỏ sang vị trí khác sau khi sửa giá trị trên trang.

Để customize các giá trị trong tag best_in_place trong views một cách đầy đủ nhất, ta có thể xem qua ý nghĩa của các tham số tại Usage best_in_place

Đây là kết quả cho ta:

alt

Ngoài ra, ta có thể tùy chỉnh giao diện bằng css, hoặc thêm các tùy biến khác cho thẻ sử dụng best_in_place:

.purr {
  position: fixed;
  top: 30px;
  right: 100px;
  width: 250px;
  padding: 20px;
  background-color: #FCC;
  border: solid 2px #666;
  &:first-letter { text-transform: uppercase };
}
<%= best_in_place @user, :bio, type: :textarea %>

Nếu muốn biến nó thành dạng check_box :

<%= best_in_place @user, :public_profile, type: :checkbox, collection: %w[No Yes] %>
  <%= best_in_place @user, :gender, type: :select, :collection [["Male", "Male"], ["Female", "Female"], ["", "Unspecified"]] %>

Cảm ơn bạn đã theo dõi bài viết, nếu có thiếu sót rất mong nhận được sự phản hồi của bạn.

Chúc bạn ngày càng yêu thích công việc của coder !

link tham khảo:

Railscast

Readme Github?view=asciicast


All Rights Reserved