12/08/2018, 15:43

ClientSideValidations

Trong bài viết này tôi sẽ giới thiệu việc sử dụng gem client_side_validations cho việc validate client-side trong Rails Cài đặt Để sử dụng client_side_validations trước tiên bạn cần thêm client_side_validations trong Gemfile và chạy bundle install gem 'client_side_validations' Tiếp theo ...

Trong bài viết này tôi sẽ giới thiệu việc sử dụng gem client_side_validations cho việc validate client-side trong Rails

Cài đặt

Để sử dụng client_side_validations trước tiên bạn cần thêm client_side_validations trong Gemfile và chạy bundle install

gem 'client_side_validations'

Tiếp theo bạn chạy lệnh để sinh ra file khởi tạo cấu hình cho client_side_validations

rails g client_side_validations:install

Sau khi chạy lệnh này bạn sẽ thấy file config/initializers/client_side_validations.rb được tạo ra. Bạn có thể thay đổi nội dung file này cho phù hợp với yêu cầu của dự án.

Ta có thể sửa lại config/initializers/client_side_validations.rb như sau để hiển thị chi tiết các lỗi của field

ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
  unless html_tag =~ /^<label/
    %{<div class="field_with_errors">#{html_tag}<label for="#{instance.send(:tag_id)}" class="message">#{instance.error_message.first}</label></div>}.html_safe
  else
    %{<div class="field_with_errors">#{html_tag}</div>}.html_safe
  end
end

Nếu bạn muốn copy assets files vào trong dự án bạn có thể chạy lệnh

rails g client_side_validations:copy_assets

Sau khi chạy lệnh này bạn sẽ thấy file app/assets/javascripts/rails.validations.js mới được thêm vào

Chú ý: khi bạn chạy copy_assets thì mỗi lần thay đổi version của client_side_validations thì bạn cần chạy lại lệnh này để cập nhật lại file mới nhất trong assets

Sử dụng

Để sử dụng client_side_validations đầu tiên bạn cần require rails.validations vào trong application.js

//= require rails.validations

Chú ý: Nếu bạn dùng Turbolinks thì bạn phải thêm require rails.validations sau khi thêm require turbolinks, để đảm bảo ClientSideValidations bắt sự kiện sau turbolinks.

Sử dụng ClientSideValidations

Trong FormBuilder bạn chỉ cần thêm tùy chọn validate: true vậy là form này đã có inline-validate tương tự với server-validate

<%= form_for @user, validate: true do |f| %>
  ...

Tuy nhiên bạn có thể validate riêng cho từng field, không nhất thiết phải validate cho cả form

<%= f.text_field :name, validate: true %>

Chú ý:

  • Trong một số trường hợp bạn muốn bỏ quả validate cho một thuộc tính nào đó trong form bạn chỉ cần thêm tùy chọn validate: false
<%= f.text_field :name, validate: false %>

Dưới đây tôi xin hướng dẫn cách validate với một model đơn giản (Person)

Đầu tiên dùng lệnh scaffold để sinh ra đầy đủ phần quản lí cho model

rails g scaffold Person name:string age:integer

Tiếp theo ta thêm validate cho model person.rb

class Person < ActiveRecord::Base
  validates :name, :age, presence: true
  validates_inclusion_of :age, in: 1..200
end

Tiếp theo sửa lại form thêm tùy chọn validate: true

<%= form_for(@person, validate: true) do |f| %>

Bạn có thể thấy việc thêm client-side validate khi sử dụng gem client_side_validations khá là đơn giản và không mất nhiều công sức

Tiếp theo tôi sẽ nói đến những kĩ thuật chuyên sâu hơn

Chỉnh sửa lại phần hiển thị lỗi

ClientSideValidations sử dụng ActiveRecord::Base.field_error_proc để hiển thị ra lỗi. Bạn có thể tham khảo ở phần trước ta sửa lại file config/initializers/client_side_validations.rb

ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
  unless html_tag =~ /^<label/
    %{<div class="field_with_errors">#{html_tag}<label for="#{instance.send(:tag_id)}" class="message">#{instance.error_message.first}</label></div>}.html_safe
  else
    %{<div class="field_with_errors">#{html_tag}</div>}.html_safe
  end
end

Việc config này đơn giản dùng chung cho tất cả các trang.

Tuy nhiên bạn có thể chỉnh sửa lại phần hiển thị lỗi của bằng javascript (không cần đến config/initializers/client_side_validations.rb)

window.ClientSideValidations.formBuilders['ActionView::Helpers::FormBuilder'] = {
  add: function(element, settings, message) {
    // custom add code here
  },

  remove: function(element, settings) {
    // custom remove code here
  }
}

Ta có 2 phương thức là add và remove

  • add dùng trong trường hợp thêm lỗi cho element. Bạn có thể dùng javascript để thêm nội dung lỗi message vào bất cứ vị trí nào bạn muốn
  • remove dùng trong trường hơp xóa bỏ lỗi của element. Bạn dùng javascript để tùy chỉnh ở đây tương tự với phương thức add

Để hiểu rõ hơn bạn có thể tham khảo trong rails.validations.js để việc viết lại phần thêm, xóa lỗi cho thuộc tính được chính xác hơn.

Enabling, Disabling, and Resetting ClientSideValidations ở client side

Như ở phần trước đã nói để sử dụng ClientSideValidations tròn form ta chỉ cần thêm tùy chọn validate: true. Tuy nhiên việc thêm tùy chọn validate: true lại không chạy được trong một số trường hợp form được render sau khi trang đã tải xong (Ajax load form).

Ta có thể thay đổi việc sử dụng ClientSideValidations cho form một cách tùy biến tại bất cứ thời điểm nào bằng javascript

Sử dụng validate với ClientSideValidations cho form, input

$(new_form).enableClientSideValidations();
$(new_input).enableClientSideValidations();

Không sử dụng validate với ClientSideValidations cho form, input

$(new_form).disableClientSideValidations();
$(new_input).disableClientSideValidations();

Khởi tạo lại validate cho form, input

$(new_form).resetClientSideValidations();
$(new_input).resetClientSideValidations();

Vậy là chúng ta đã hoàn thành việc sử dụng ClientSideValidations trong Rails Cảm ơn bạn đã theo dõi bài viêt !

0