diff --git a/README.md b/README.md index 89ec83d..b111cc0 100644 --- a/README.md +++ b/README.md @@ -102,9 +102,18 @@ There are four ways to cancel the automatic HTML5 validation. Set `auto_html5_validation: false` to `form_for` parameter. -* View +* View (disabling all) ```erb <%= form_for @user, auto_html5_validation: false do |f| %> + + ... +<% end %> +``` + +* View (disabling specific validation) +```erb +<%= form_for @user, auto_html5_validation: {required: false} do |f| %> + ... <% end %> ``` @@ -113,11 +122,16 @@ Set `auto_html5_validation: false` to `form_for` parameter. Set `auto_html5_validation = false` attribute to ActiveModelish object. -* Controller +* Controller (disabling all) ```ruby @user = User.new auto_html5_validation: false ``` +* Controller (disabling specific validation) +```ruby +@user = User.new auto_html5_validation: {required: false} +``` + * View ```erb <%= form_for @user do |f| %> @@ -129,13 +143,20 @@ Set `auto_html5_validation = false` attribute to ActiveModelish object. Set `auto_html5_validation = false` to ActiveModelish class variable. -* Model +* Model (disabling all) ```ruby class User < ActiveRecord::Base self.auto_html5_validation = false end ``` +* Model (disabling specific validation) +```ruby +class User < ActiveRecord::Base + self.auto_html5_validation: {required: false} +end +``` + * Controller ```ruby @user = User.new @@ -150,7 +171,18 @@ end ### 4. Globally (via HTML5Validators module configuration) -Set `config.enabled = false` to Html5Validators module. +* disabling all validation +```ruby +Html5Validators.enabled = false +``` + +* disabling specific validation +```ruby +Html5Validators.configure do |config| + config.validation[:required] = false +end +``` + Maybe you want to put this in your test_helper, or add a controller filter as follows for development mode. diff --git a/lib/html5_validators.rb b/lib/html5_validators.rb index 0feaf4f..f40a1b6 100644 --- a/lib/html5_validators.rb +++ b/lib/html5_validators.rb @@ -1,4 +1,5 @@ require 'rails' +require 'html5_validators/config' module Html5Validators @enabled = true @@ -11,6 +12,15 @@ def self.enabled=(enable) @enabled = enable end + class << self + def validation_enabled?(validation, object) + enabled && config.validation[validation] && + object.class.ancestors.include?(ActiveModel::Validations) && + !(object.auto_html5_validation == false || object.auto_html5_validation.try(:[], validation) == false) && + !(object.class.auto_html5_validation == false || object.class.auto_html5_validation.try(:[], validation) == false) + end + end + class Railtie < ::Rails::Railtie #:nodoc: initializer 'html5_validators' do |app| ActiveSupport.on_load(:active_record) do diff --git a/lib/html5_validators/action_view/form_helpers.rb b/lib/html5_validators/action_view/form_helpers.rb index 75bb35a..69ab653 100644 --- a/lib/html5_validators/action_view/form_helpers.rb +++ b/lib/html5_validators/action_view/form_helpers.rb @@ -3,8 +3,8 @@ module ActionViewExtension module FormHelper def form_for(record, options = {}, &block) if record.respond_to?(:auto_html5_validation=) - if !Html5Validators.enabled || (options[:auto_html5_validation] == false) - record.auto_html5_validation = false + if options.key?(:auto_html5_validation) + record.auto_html5_validation = options[:auto_html5_validation] end end super @@ -13,29 +13,23 @@ def form_for(record, options = {}, &block) module PresenceValidator def render - if object.class.ancestors.include?(ActiveModel::Validations) && (object.auto_html5_validation != false) && (object.class.auto_html5_validation != false) - @options["required"] ||= @options[:required] || object.class.attribute_required?(@method_name) - end + @options["required"] ||= @options[:required] || object.class.attribute_required?(@method_name) if Html5Validators.validation_enabled?(:required, object) super end end module LengthValidator def render - if object.class.ancestors.include?(ActiveModel::Validations) && (object.auto_html5_validation != false) && (object.class.auto_html5_validation != false) - @options["maxlength"] ||= @options[:maxlength] || object.class.attribute_maxlength(@method_name) - @options["minlength"] ||= @options[:minlength] || object.class.attribute_minlength(@method_name) - end + @options["maxlength"] ||= @options[:maxlength] || object.class.attribute_maxlength(@method_name) if Html5Validators.validation_enabled?(:maxlength, object) + @options["minlength"] ||= @options[:minlength] || object.class.attribute_minlength(@method_name) if Html5Validators.validation_enabled?(:minlength, object) super end end module NumericalityValidator def render - if object.class.ancestors.include?(ActiveModel::Validations) && (object.auto_html5_validation != false) && (object.class.auto_html5_validation != false) - @options["max"] ||= @options["max"] || @options[:max] || object.class.attribute_max(@method_name) - @options["min"] ||= @options["min"] || @options[:min] || object.class.attribute_min(@method_name) - end + @options["max"] ||= @options["max"] || @options[:max] || object.class.attribute_max(@method_name) if Html5Validators.validation_enabled?(:max, object) + @options["min"] ||= @options["min"] || @options[:min] || object.class.attribute_min(@method_name) if Html5Validators.validation_enabled?(:min, object) super end end diff --git a/lib/html5_validators/action_view/form_helpers_rails3.rb b/lib/html5_validators/action_view/form_helpers_rails3.rb index fa37fcf..c0fa6f8 100644 --- a/lib/html5_validators/action_view/form_helpers_rails3.rb +++ b/lib/html5_validators/action_view/form_helpers_rails3.rb @@ -4,8 +4,8 @@ module Helpers module FormHelper def form_for_with_auto_html5_validation_option(record, options = {}, &proc) if record.respond_to?(:auto_html5_validation=) - if !Html5Validators.enabled || (options[:auto_html5_validation] == false) - record.auto_html5_validation = false + if options.key?(:auto_html5_validation) + record.auto_html5_validation = options[:auto_html5_validation] end end form_for_without_auto_html5_validation_option record, options, &proc @@ -15,39 +15,35 @@ def form_for_with_auto_html5_validation_option(record, options = {}, &proc) class InstanceTag def to_input_field_tag_with_html5_attributes(field_type, options = {}) - if object.class.ancestors.include?(ActiveModel::Validations) && (object.auto_html5_validation != false) && (object.class.auto_html5_validation != false) - options["required"] ||= object.class.attribute_required?(method_name) - options["maxlength"] ||= object.class.attribute_maxlength(method_name) - options["minlength"] ||= object.class.attribute_minlength(method_name) - options["max"] ||= object.class.attribute_max(method_name) - options["min"] ||= object.class.attribute_min(method_name) - end + options["required"] ||= object.class.attribute_required?(method_name) if Html5Validators.validation_enabled?(:required, object) + options["maxlength"] ||= object.class.attribute_maxlength(method_name) if Html5Validators.validation_enabled?(:maxlength, object) + options["minlength"] ||= object.class.attribute_minlength(method_name) if Html5Validators.validation_enabled?(:minlength, object) + options["max"] ||= object.class.attribute_max(method_name) if Html5Validators.validation_enabled?(:max, object) + options["min"] ||= object.class.attribute_min(method_name) if Html5Validators.validation_enabled?(:min, object) + to_input_field_tag_without_html5_attributes field_type, options end alias_method_chain :to_input_field_tag, :html5_attributes def to_text_area_tag_with_html5_attributes(options = {}) - if object.class.ancestors.include?(ActiveModel::Validations) && (object.auto_html5_validation != false) && (object.class.auto_html5_validation != false) - options["required"] ||= object.class.attribute_required?(method_name) - options["maxlength"] ||= object.class.attribute_maxlength(method_name) - options["minlength"] ||= object.class.attribute_minlength(method_name) - end + options["required"] ||= object.class.attribute_required?(method_name) if Html5Validators.validation_enabled?(:required, object) + options["maxlength"] ||= object.class.attribute_maxlength(method_name) if Html5Validators.validation_enabled?(:maxlength, object) + options["minlength"] ||= object.class.attribute_minlength(method_name) if Html5Validators.validation_enabled?(:minlength, object) + to_text_area_tag_without_html5_attributes options end alias_method_chain :to_text_area_tag, :html5_attributes def to_radio_button_tag_with_html5_attributes(tag_value, options = {}) - if object.class.ancestors.include?(ActiveModel::Validations) && (object.auto_html5_validation != false) && (object.class.auto_html5_validation != false) - options["required"] ||= object.class.attribute_required?(method_name) - end + options["required"] ||= object.class.attribute_required?(method_name) if Html5Validators.validation_enabled?(:required, object) + to_radio_button_tag_without_html5_attributes tag_value, options end alias_method_chain :to_radio_button_tag, :html5_attributes def to_check_box_tag_with_html5_attributes(options = {}, checked_value = "1", unchecked_value = "0") - if object.class.ancestors.include?(ActiveModel::Validations) && (object.auto_html5_validation != false) && (object.class.auto_html5_validation != false) - options["required"] ||= object.class.attribute_required?(method_name) - end + options["required"] ||= object.class.attribute_required?(method_name) if Html5Validators.validation_enabled?(:required, object) + to_check_box_tag_without_html5_attributes options, checked_value, unchecked_value end alias_method_chain :to_check_box_tag, :html5_attributes diff --git a/lib/html5_validators/action_view/form_helpers_ruby1.rb b/lib/html5_validators/action_view/form_helpers_ruby1.rb index 2ff73ab..94403ab 100644 --- a/lib/html5_validators/action_view/form_helpers_ruby1.rb +++ b/lib/html5_validators/action_view/form_helpers_ruby1.rb @@ -2,23 +2,17 @@ module Html5Validators module ActionViewExtension def inject_required_attribute - if object.class.ancestors.include?(ActiveModel::Validations) && (object.auto_html5_validation != false) && (object.class.auto_html5_validation != false) - @options["required"] ||= @options[:required] || object.class.attribute_required?(@method_name) - end + @options["required"] ||= @options[:required] || object.class.attribute_required?(@method_name) if Html5Validators.validation_enabled?(:required, object) end def inject_maxlength_attribute - if object.class.ancestors.include?(ActiveModel::Validations) && (object.auto_html5_validation != false) && (object.class.auto_html5_validation != false) - @options["maxlength"] ||= @options[:maxlength] || object.class.attribute_maxlength(@method_name) - @options["minlength"] ||= @options[:minlength] || object.class.attribute_minlength(@method_name) - end + @options["maxlength"] ||= @options[:maxlength] || object.class.attribute_maxlength(@method_name) if Html5Validators.validation_enabled?(:maxlength, object) + @options["minlength"] ||= @options[:minlength] || object.class.attribute_minlength(@method_name) if Html5Validators.validation_enabled?(:minlength, object) end def inject_numericality_attributes - if object.class.ancestors.include?(ActiveModel::Validations) && (object.auto_html5_validation != false) && (object.class.auto_html5_validation != false) - @options["max"] ||= @options["max"] || @options[:max] || object.class.attribute_max(@method_name) - @options["min"] ||= @options["min"] || @options[:min] || object.class.attribute_min(@method_name) - end + @options["max"] ||= @options["max"] || @options[:max] || object.class.attribute_max(@method_name) if Html5Validators.validation_enabled?(:max, object) + @options["min"] ||= @options["min"] || @options[:min] || object.class.attribute_min(@method_name) if Html5Validators.validation_enabled?(:min, object) end end end @@ -29,8 +23,8 @@ module Helpers module FormHelper def form_for_with_auto_html5_validation_option(record, options = {}, &proc) if record.respond_to?(:auto_html5_validation=) - if !Html5Validators.enabled || (options[:auto_html5_validation] == false) - record.auto_html5_validation = false + if options.key?(:auto_html5_validation) + record.auto_html5_validation = options[:auto_html5_validation] end end form_for_without_auto_html5_validation_option record, options, &proc diff --git a/lib/html5_validators/config.rb b/lib/html5_validators/config.rb new file mode 100644 index 0000000..e979d2f --- /dev/null +++ b/lib/html5_validators/config.rb @@ -0,0 +1,27 @@ +module Html5Validators + class << self + def configure + yield config + end + + def config + @config ||= Configuration.new + end + end + + class Configuration + include ActiveSupport::Configurable + + config_accessor :validation + end + + configure do |config| + config.validation = { + :required => true, + :maxlength => true, + :minlength => true, + :max => true, + :min => true + } + end +end diff --git a/spec/fake_app.rb b/spec/fake_app.rb index 2c6f88f..c0e30d4 100644 --- a/spec/fake_app.rb +++ b/spec/fake_app.rb @@ -16,12 +16,14 @@ resources :people, :only => [:new, :create] do collection do get :new_without_html5_validation + get :new_without_required_html5_validation get :new_with_required_true end end resources :items, :only => [:new, :create] do collection do get :new_without_html5_validation + get :new_without_required_html5_validation get :new_with_required_true end end @@ -65,6 +67,16 @@ def new_without_html5_validation ERB end + def new_without_required_html5_validation + @person = Person.new + render :inline => <<-ERB +<%= form_for @person, :auto_html5_validation => {:required => false} do |f| %> +<%= f.text_field :name %> +<%= f.text_field :email %> +<% end %> +ERB + end + def new_with_required_true @person = Person.new render :inline => <<-ERB @@ -95,6 +107,16 @@ def new_without_html5_validation ERB end + def new_without_required_html5_validation + @item = Item.new + render :inline => <<-ERB +<%= form_for @item, :auto_html5_validation => {:required => false} do |f| %> +<%= f.text_field :name %> +<%= f.text_area :description %> +<% end %> +ERB + end + def new_with_required_true @item = Item.new render :inline => <<-ERB diff --git a/spec/features/validation_spec.rb b/spec/features/validation_spec.rb index 57f15f9..3552de7 100644 --- a/spec/features/validation_spec.rb +++ b/spec/features/validation_spec.rb @@ -33,6 +33,11 @@ find('input#person_name')[:required].should be_nil end + scenario 'new_without_required_html5_validation form' do + visit '/people/new_without_required_html5_validation' + + find('input#person_name')[:required].should be_nil + end scenario 'new_with_required_true form' do visit '/people/new_with_required_true' @@ -40,35 +45,78 @@ end context 'disabling html5_validation in class level' do - background do - Person.class_eval do |kls| - kls.auto_html5_validation = false + context 'disabling all' do + background do + Person.class_eval do |kls| + kls.auto_html5_validation = false + end end - end - after do - Person.class_eval do |kls| - kls.auto_html5_validation = nil + after do + Person.class_eval do |kls| + kls.auto_html5_validation = nil + end + end + scenario 'new form' do + visit '/people/new' + + find('input#person_name')[:required].should be_nil end end - scenario 'new form' do - visit '/people/new' - find('input#person_name')[:required].should be_nil + context 'disabling requied only' do + background do + Person.class_eval do |kls| + kls.auto_html5_validation = {:required => false} + end + end + after do + Person.class_eval do |kls| + kls.auto_html5_validation = nil + end + end + scenario 'new form' do + visit '/people/new' + + find('input#person_name')[:required].should be_nil + end end end context 'disabling html5_validations in gem' do - background do - Html5Validators.enabled = false - end - after do - Html5Validators.enabled = true + context 'disabling all' do + background do + Html5Validators.enabled = false + end + after do + Html5Validators.enabled = true + end + scenario 'new form' do + visit '/people/new' + + find('input#person_name')[:required].should be_nil + find('textarea#person_bio')[:required].should be_nil + end end - scenario 'new form' do - visit '/people/new' - find('input#person_name')[:required].should be_nil - find('textarea#person_bio')[:required].should be_nil + context 'disabling required only' do + background do + Html5Validators.configure do |config| + config.validation[:required] = false + end + end + + after do + Html5Validators.configure do |config| + config.validation[:required] = true + end + end + + scenario 'new form' do + visit '/items/new' + + find('input#item_name')[:required].should be_nil + find('textarea#item_description')[:required].should be_nil + end end end end @@ -135,6 +183,11 @@ find('input#item_name')[:required].should be_nil end + scenario 'new_without_required_html5_validation form' do + visit '/items/new_without_required_html5_validation' + + find('input#item_name')[:required].should be_nil + end scenario 'new_with_required_true form' do visit '/items/new_with_required_true' @@ -142,35 +195,78 @@ end context 'disabling html5_validation in class level' do - background do - Item.class_eval do |kls| - kls.auto_html5_validation = false + context 'disabling all' do + background do + Item.class_eval do |kls| + kls.auto_html5_validation = false + end end - end - after do - Item.class_eval do |kls| - kls.auto_html5_validation = nil + after do + Item.class_eval do |kls| + kls.auto_html5_validation = nil + end + end + scenario 'new form' do + visit '/items/new' + + find('input#item_name')[:required].should be_nil end end - scenario 'new form' do - visit '/items/new' - find('input#item_name')[:required].should be_nil + context 'disabling required only' do + background do + Item.class_eval do |kls| + kls.auto_html5_validation = {:required => false} + end + end + after do + Item.class_eval do |kls| + kls.auto_html5_validation = nil + end + end + scenario 'new form' do + visit '/items/new' + + find('input#item_name')[:required].should be_nil + end end end context 'disabling html5_validations in gem' do - background do - Html5Validators.enabled = false - end - after do - Html5Validators.enabled = true + context 'disabling all' do + background do + Html5Validators.enabled = false + end + after do + Html5Validators.enabled = true + end + scenario 'new form' do + visit '/items/new' + + find('input#item_name')[:required].should be_nil + find('textarea#item_description')[:required].should be_nil + end end - scenario 'new form' do - visit '/items/new' - find('input#item_name')[:required].should be_nil - find('textarea#item_description')[:required].should be_nil + context 'disabling required only' do + background do + Html5Validators.configure do |config| + config.validation[:required] = false + end + end + + after do + Html5Validators.configure do |config| + config.validation[:required] = true + end + end + + scenario 'new form' do + visit '/items/new' + + find('input#item_name')[:required].should be_nil + find('textarea#item_description')[:required].should be_nil + end end end end