Client validation
I. Client validation? Nhằm hợp lệ dữ liệu trước khi được submit lên server Nó không require bất cứ một script nào từ phía server Làm giảm lỗi trước khi dữ liệu được gửi lên server-side II. Client side validation gem 1. Feature Tự động apply validate cho phía client dựa vào model ...
I. Client validation?
Nhằm hợp lệ dữ liệu trước khi được submit lên server
Nó không require bất cứ một script nào từ phía server
Làm giảm lỗi trước khi dữ liệu được gửi lên server-side
II. Client side validation gem
1. Feature
-
Tự động apply validate cho phía client dựa vào model
-
Trong trường hợp mà rule validate ở phía server-side không áp dụng được với phía client, nó sẽ không attempt cho client và quay trở lại validate ở server-side
-
Tương thích với nhiều trình duyệt
-
tương thích với ActiveModel::Validations
-
Validate cho nested field
-
Hỗ trợ custom validate
-
Client side callback
-
Hệ thống Plugin hỗ trợ FormBuilders, ORMs...
2. Install
Trước khi dùng client side validation gem hãy chắc chắn là bạn đã cài jquery-rails gem
Cài gem
gem client_side_validations
Trên màn hình terminal run lệnh:
rails g client_side_validations:install
Sẽ sinh ra
$ rails g client_side_validations:install create config/initializers/client_side_validations.rb create public/javascripts/rails.validations.js
Thêm đoạn code sau vào ```
/app/views/layouts/application.html.erb
Trong file config/initializers/client_side_validations.rb
Mặc định code trong file sẽ bị comment sử dụng cho Formtastic và Formbuilder và override method field_error_proc, muôn dùng nó đối với form bình thường bạn phải uncomment nó
ActionView::Base.field_error_proc = Proc.new do |html_tag, instance| unless html_tag =~ /^<label/ %{ `#{html_tag}<label for="#{instance.send(:tag_id)}"># {instance.error_message.first}</label>}.html_safe else%{#{html_tag}}.html_safe end end
Phương thức này sẽ append vào label một messge lỗi đối với bất kỳ trường nào lỗi
Điều chú ý tiếp theo là cần phải add opption vào form. validate: true
3. Custom validateGiả sử ta cần validate email theo cách riêng có thể làm như sau:
- Tạo ra một file
/lib/email_format_validator.rb
class EmailFormatValidator < ActiveModel::EachValidator def validate_each(object, attribute, value) unless value =~ /^([^@s]+)@((?:[-a-z0-9]+.)+[a-z]{2,})$/i object.errors[attribute] << (options[:message] || "is not formatted properly") end end end
Để rõ hơn về phương thức này hãy tham khảo trang sau: http://asciicasts.com/episodes/211-validations-in-rails-3
Đối với rails 3 không tự động load /lib vào application.rb cần phải load như sau
/config/application.rb
require File.expand_path('../boot', __FILE__) require 'rails/all' Bundler.require(:default, Rails.env) if defined?(Bundler) module Validator class Application < Rails::Application config.autoload_paths << "#{config.root}/lib" # Configure the default encoding used in templates for Ruby 1.9. config.encoding = "utf-8" # Configure sensitive parameters which will be filtered from the log file. config.filter_parameters += [:password] end end
- Việc hiển thị lỗi được cấu hình trong locale /config/locales/en.yml
en: errors: messages: email_format: "is not formatted properly." - Trong model cần gọi custom validate email_format: true ( đã tạo ở trên /lib/email_format_validator.rb) validates :email, :email_format => true
Như vậy là đủ để khi submit form bên server sẽ xử lý việc validate, nhưng để khi nhập email không hợp lệ và tab sang text field khác cần phải thông báo lỗi, việc này là do một gem gửi đi một ajax request lên server, cấu hình như sau:
/public/javascripts/rails.validations.custom.js
clientSideValidations.validators.local["email_format"] = function (element, options) { if(!/^([^@s]+)@((?:[-a-z0-9]+.)+[a-z]{2,})$/i.test(element.val())) { return options.message; } }
Để thêm javascript validate vào ứng dụng cần phải thêm một đoạn code ruby sau:
/app/views/layouts/application.html.erb
III. Tham khảo
Nguồn tham khảo:
http://railscasts.com/episodes/263-client-side-validations?view=asciicast
http://asciicasts.com/episodes/211-validations-in-rails-3
https://github.com/bcardarella/client_side_validations