Skip to content

Commit

Permalink
Support disabling specific validation
Browse files Browse the repository at this point in the history
  • Loading branch information
mtsmfm committed Aug 14, 2015
1 parent 5d7f9ca commit e0e77b2
Show file tree
Hide file tree
Showing 8 changed files with 259 additions and 88 deletions.
40 changes: 36 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 %>
```
Expand All @@ -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| %>
Expand All @@ -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
Expand All @@ -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.

Expand Down
10 changes: 10 additions & 0 deletions lib/html5_validators.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'rails'
require 'html5_validators/config'

module Html5Validators
@enabled = true
Expand All @@ -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
Expand Down
20 changes: 7 additions & 13 deletions lib/html5_validators/action_view/form_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
36 changes: 16 additions & 20 deletions lib/html5_validators/action_view/form_helpers_rails3.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
20 changes: 7 additions & 13 deletions lib/html5_validators/action_view/form_helpers_ruby1.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
27 changes: 27 additions & 0 deletions lib/html5_validators/config.rb
Original file line number Diff line number Diff line change
@@ -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
22 changes: 22 additions & 0 deletions spec/fake_app.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
Loading

0 comments on commit e0e77b2

Please sign in to comment.