wanew_client_validate 0.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 [name of plugin creator]
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/init.rb ADDED
@@ -0,0 +1,3 @@
1
+ # Include hook code here
2
+
3
+ require 'client_validate'
@@ -0,0 +1,16 @@
1
+ module WaNew
2
+ module ClientValidate
3
+ module ActionView
4
+ module Helpers
5
+
6
+ end
7
+ end
8
+ end
9
+ end
10
+
11
+
12
+ require 'wanew/client_validate/action_view/form_helper'
13
+ require 'wanew/client_validate/action_view/form_builder'
14
+
15
+ ActionView::Base.send(:include, WaNew::ClientValidate::ActionView::Helpers::FormHelper)
16
+ ActionView::Helpers::FormBuilder.send(:include, WaNew::ClientValidate::ActionView::Helpers::FormBuilder)
@@ -0,0 +1,103 @@
1
+ module WaNew::ClientValidate::ActionView::Helpers
2
+ module FormBuilder
3
+
4
+ def self.included(base)
5
+ (base.field_helpers - %w(apply_form_for_options! label check_box radio_button fields_for hidden_field)).each do |selector|
6
+ base.class_eval <<-RUBY_EVAL
7
+ def #{selector}_with_client_validations(method, options = {})
8
+ apply_client_validators(method, options)
9
+ options.delete(:validate)
10
+ #{selector}_without_client_validations(method, options)
11
+ end
12
+ RUBY_EVAL
13
+
14
+ base.class_eval { alias_method_chain selector, :client_validations }
15
+ end
16
+
17
+ base.class_eval do
18
+ alias_method_chain :initialize, :client_validations
19
+ alias_method_chain :fields_for, :client_validations
20
+ alias_method_chain :check_box, :client_validations
21
+ alias_method_chain :radio_button, :client_validations
22
+ alias_method_chain :select, :client_validations
23
+ alias_method_chain :collection_select, :client_validations
24
+ alias_method_chain :grouped_collection_select, :client_validations
25
+ alias_method_chain :time_zone_select, :client_validations
26
+
27
+ def self.client_form_settings(options, form_helper)
28
+ {
29
+ #:type => self.to_s,
30
+ #:input_tag => form_helper.class.field_error_proc.call(%{<span id="input_tag" />}, Struct.new(:error_message, :tag_id).new([], "")),
31
+ #:label_tag => form_helper.class.field_error_proc.call(%{<label id="label_tag" />}, Struct.new(:error_message, :tag_id).new([], ""))
32
+ }
33
+ end
34
+ end
35
+ end
36
+
37
+ def initialize_with_client_validations(object_name, object, template, options, proc)
38
+ initialize_without_client_validations(object_name, object, template, options, proc)
39
+ @options[:validators] = {}
40
+ end
41
+
42
+ def fields_for_with_client_validations(record_or_name_or_array, *args, &block)
43
+ options = args.extract_options!
44
+ options[:validate] ||= @options[:validate] if @options[:validate] && !options.key?(:validate)
45
+ fields_for_without_client_validations(record_or_name_or_array, *(args << options), &block)
46
+ end
47
+
48
+ def check_box_with_client_validations(method, options = {}, checked_value = "1", unchecked_value = "0")
49
+ apply_client_validators(method, options)
50
+ check_box_without_client_validations(method, options, checked_value, unchecked_value)
51
+ end
52
+
53
+ def radio_button_with_client_validations(method, tag_value, options = {})
54
+ apply_client_validators(method, options)
55
+ radio_button_without_client_validations(method, tag_value, options)
56
+ end
57
+
58
+ def select_with_client_validations(method, choices, options = {}, html_options = {})
59
+ apply_client_validators(method, html_options)
60
+ select_without_client_validations(method, choices, options, html_options)
61
+ end
62
+
63
+ def collection_select_with_client_validations(method, collection, value_method, text_method, options = {}, html_options = {})
64
+ apply_client_validators(method, html_options)
65
+ collection_select_without_client_validations(method, collection, value_method, text_method, options, html_options)
66
+ end
67
+
68
+ def grouped_collection_select_with_client_validations(method, collection, group_method, group_label_method, option_key_method, option_value_method, options = {}, html_options = {})
69
+ apply_client_validators(method, html_options)
70
+ grouped_collection_select_without_client_validations(method, collection, group_method, group_label_method, option_key_method, option_value_method, options, html_options)
71
+ end
72
+
73
+ def time_zone_select_with_client_validations(method, priority_zones = nil, options = {}, html_options = {})
74
+ apply_client_validators(method, html_options)
75
+ time_zone_select_without_client_validations(method, priority_zones = nil, options, html_options)
76
+ end
77
+
78
+ private
79
+
80
+ def apply_client_validators(method, options = {})
81
+ if @options[:validate] && options[:validate] != false && validators = filter_validators(@object.client_validation_hash[method], options[:validate])
82
+
83
+ options.merge!("validate" => validators.to_json)
84
+
85
+ @options[:validators].merge!("#{@object_name}[#{method}]" => validators)
86
+ end
87
+ end
88
+
89
+ def filter_validators(validators, filters)
90
+ if validators
91
+ filtered_validators = validators.inject({}) do |filtered_validators, validator|
92
+ unless filters && filters.key?(validator.first) && !filters[validator.first]
93
+ filtered_validators[validator.first] = validator.last
94
+ end
95
+
96
+ filtered_validators
97
+ end
98
+
99
+ filtered_validators.empty? ? nil : filtered_validators
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,76 @@
1
+ module WaNew::ClientValidate::ActionView::Helpers
2
+ module FormHelper
3
+ def form_for(record_or_name_or_array, *args, &proc)
4
+ raise ArgumentError, "Missing block" unless block_given?
5
+
6
+ options = args.extract_options!
7
+
8
+ case record_or_name_or_array
9
+ when String, Symbol
10
+ ActiveSupport::Deprecation.warn("Using form_for(:name, @resource) is deprecated. Please use form_for(@resource, :as => :name) instead.", caller) unless args.empty?
11
+ object_name = record_or_name_or_array
12
+ when Array
13
+ object = record_or_name_or_array.last
14
+ object_name = options[:as] || ActiveModel::Naming.singular(object)
15
+ apply_form_for_options!(record_or_name_or_array, options)
16
+ args.unshift object
17
+ else
18
+ object = record_or_name_or_array
19
+ object_name = options[:as] || ActiveModel::Naming.singular(object)
20
+ apply_form_for_options!([object], options)
21
+ args.unshift object
22
+ end
23
+
24
+ (options[:html] ||= {})[:remote] = true if options.delete(:remote)
25
+
26
+ @validators = {}
27
+ # Order matters here. Rails mutates the options object
28
+ script = client_form_settings(object, options)
29
+ form = super(record_or_name_or_array, *(args << options), &proc)
30
+ # Because of the load order requirement above this sub is necessary
31
+ # Would be nice to not do this
32
+ "#{form}#{script ? script.sub('"validator_hash"', @validators.to_json) : nil}#{script_bind(dom_id(object))}".html_safe
33
+ end
34
+
35
+
36
+ def apply_form_for_options!(object_or_array, options)
37
+ super
38
+ options[:html][:validate] = true if options[:validate]
39
+ end
40
+
41
+ def fields_for(record_or_name_or_array, *args, &block)
42
+ output = super
43
+ @validators.merge!(args.last[:validators]) if @validators
44
+ output
45
+ end
46
+
47
+ private
48
+
49
+ def client_form_settings(object, options)
50
+ if options[:validate]
51
+ builder = options[:builder] || ActionView::Base.default_form_builder
52
+ if options[:html] && options[:html][:id]
53
+ var_name = options[:html][:id]
54
+ else
55
+ var_name = if object.respond_to?(:persisted?) && object.persisted?
56
+ options[:as] ? "#{options[:as]}_edit" : dom_id(object, :edit)
57
+ else
58
+ options[:as] ? "#{options[:as]}_new" : dom_id(object)
59
+ end
60
+ end
61
+
62
+ content_tag(:script, :type=>'text/javascript') do
63
+ "var #{var_name} = #{builder.client_form_settings(options, self).merge(:validators => 'validator_hash').to_json};".html_safe
64
+ end
65
+
66
+ end
67
+ end
68
+
69
+ def script_bind(id)
70
+ content_tag(:script, :type=>'text/javascript') do
71
+ "$('##{id}').validate();"
72
+ end
73
+ end
74
+
75
+ end
76
+ end
@@ -0,0 +1,14 @@
1
+ module WaNew
2
+ module ClientValidate
3
+ module ActiveModel
4
+ end
5
+ end
6
+ end
7
+
8
+ require 'active_model/validator'
9
+
10
+ require 'wanew/client_validate/active_model/validators'
11
+ require 'wanew/client_validate/active_model/validator'
12
+
13
+ ActiveModel::Validations::HelperMethods.send(:include,
14
+ WaNew::ClientValidate::ActionView::Validations::HelperMethods) if defined?(:ActiveModel)
@@ -0,0 +1,44 @@
1
+ module WaNew::ClientValidate::ActiveModel
2
+ module Validator
3
+
4
+ def client_hash(model, attribute)
5
+ extra_options = options.except(*::ActiveModel::Errors::CALLBACKS_OPTIONS - [:on, :allow_blank])
6
+ { :message => model.errors.generate_message(attribute, message_type, extra_options) }.merge(extra_options)
7
+ end
8
+
9
+ private
10
+
11
+ def message_type
12
+ kind
13
+ end
14
+ end
15
+
16
+ module Validations
17
+ def client_validation_hash
18
+ _validators.except(nil, :block).inject({}) do |attr_hash, attr|
19
+
20
+ validator_hash = attr[1].inject({}) do |kind_hash, validator|
21
+ client_hash = validator.client_hash(self, attr[0])
22
+ # Yeah yeah, #new_record? is not part of ActiveModel :p
23
+ if (can_use_for_client_validation?(client_hash, validator))
24
+ kind_hash.merge!(validator.kind => client_hash.except(:on))
25
+ else
26
+ kind_hash.merge!({})
27
+ end
28
+ end
29
+
30
+ attr_hash.merge!(attr[0] => validator_hash)
31
+ end.delete_if { |key, value| value.blank? }
32
+ end
33
+
34
+ private
35
+
36
+ def can_use_for_client_validation?(client_hash, validator)
37
+ ((self.respond_to?(:new_record?) && client_hash[:on] == (self.new_record? ? :create : :update)) || client_hash[:on].nil?) && !validator.options.key?(:if) && !validator.options.key?(:unless) && validator.kind != :block
38
+ end
39
+ end
40
+ end
41
+
42
+
43
+ ActiveModel::Validator.send(:include, WaNew::ClientValidate::ActiveModel::Validator)
44
+ ActiveModel::Validations.send(:include, WaNew::ClientValidate::ActiveModel::Validations)
@@ -0,0 +1,20 @@
1
+ module WaNew::ClientValidate::ActionView::Validations
2
+ module HelperMethods
3
+
4
+ def self.included(base)
5
+ base.class_eval do
6
+
7
+ def validates_presence_of_with_client(*attr_names)
8
+ options = attr_names.extract_options!
9
+ options[:message] ||= ""
10
+ options[:message] += " with client!"
11
+ attr_names << options;
12
+
13
+ validates_presence_of_without_client(*attr_names)
14
+ end
15
+
16
+ alias_method_chain :validates_presence_of, :client
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,11 @@
1
+ require 'wanew/client_validate/active_model'
2
+ require 'wanew/client_validate/active_record/middleware'
3
+
4
+ %w{uniqueness}.each do |validator|
5
+ require "wanew/client_validate/active_record/#{validator}"
6
+ validator.capitalize!
7
+ eval "ActiveRecord::Validations::#{validator}Validator.send(:include, WaNew::ClientValidate::ActiveRecord::#{validator})"
8
+ end
9
+
10
+ ActiveRecord::Base.send(:include, WaNew::ClientValidate::ActiveModel::Validations)
11
+
@@ -0,0 +1,29 @@
1
+ module WaNew::ClientValidate::ActiveRecord
2
+ class Middleware
3
+
4
+ def self.is_unique?(klass, attribute, value, params)
5
+ column = klass.columns_hash[attribute.to_s]
6
+ value = column.limit ? value.to_s.mb_chars[0, column.limit] : value.to_s if column.text?
7
+
8
+ t = klass.arel_table
9
+
10
+ if params[:case_sensitive] == 'true'
11
+ if t.engine.connection.instance_variable_get("@config")[:adapter] == 'mysql'
12
+ relation = Arel::Nodes::SqlLiteral.new("BINARY #{t[attribute].eq(value).to_sql}")
13
+ else
14
+ relation = t[attribute].eq(value)
15
+ end
16
+ else
17
+ relation = t[attribute].matches(value)
18
+ end
19
+
20
+ relation = relation.and(t.primary_key.not_eq(params[:id])) if params[:id]
21
+
22
+ (params[:scope] || {}).each do |key, value|
23
+ relation = relation.and(t[key].eq(value))
24
+ end
25
+
26
+ !klass.where(relation).exists?
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,26 @@
1
+ module WaNew::ClientValidate::ActiveRecord
2
+ module Uniqueness
3
+ def client_hash(model, attribute)
4
+ extra_options = options.except(*::ActiveModel::Errors::CALLBACKS_OPTIONS - [:on, :allow_blank])
5
+ hash = { :message => model.errors.generate_message(attribute, message_type, extra_options.except(:case_sensitive, :scope)) }
6
+ hash = hash.merge(extra_options).merge(model.new_record? ? {} : { :id => model.id })
7
+
8
+ if hash[:scope].present?
9
+ hash[:scope] = Array.wrap(hash[:scope]).inject({}) do |scope_hash, scope_item|
10
+ scope_hash.merge!(scope_item => model.send(scope_item))
11
+ end
12
+ else
13
+ hash.delete(:scope)
14
+ end
15
+
16
+ hash
17
+ end
18
+
19
+ private
20
+
21
+ def message_type
22
+ :taken
23
+ end
24
+ end
25
+ end
26
+
@@ -0,0 +1,81 @@
1
+ # encoding: utf-8
2
+
3
+ module WaNew::ClientValidate
4
+
5
+ module Middleware
6
+
7
+ class Validators
8
+ def initialize(app)
9
+ @app = app
10
+ end
11
+
12
+ def call(env)
13
+ case env['PATH_INFO']
14
+ when %r{\/validators\/(\w+)\.json}
15
+ "::WaNew::ClientValidate::Middleware::#{$1.camelize}".constantize.new(env).response
16
+ else
17
+ @app.call(env)
18
+ end
19
+ end
20
+ end
21
+
22
+ class Base
23
+ attr_accessor :request, :body, :status
24
+
25
+ def initialize(env)
26
+ self.body = ''
27
+ self.status = 200
28
+ self.request = ActionDispatch::Request.new(env)
29
+ end
30
+
31
+ def response
32
+ [status, {'Content-Type' => content_type, 'Content-Length' => body.length.to_s}, [body]]
33
+ end
34
+
35
+ def content_type
36
+ 'application/json'
37
+ end
38
+ end
39
+
40
+ class Uniqueness < Base
41
+ IGNORE_PARAMS = %w{case_sensitive id scope}
42
+
43
+ def response
44
+ if is_unique?
45
+ self.status = 404
46
+ self.body = 'true'
47
+ else
48
+ self.status = 200
49
+ self.body = 'false'
50
+ end
51
+ super
52
+ end
53
+
54
+ private
55
+
56
+ def is_unique?
57
+ resource = extract_resource
58
+ klass = resource.classify.constantize
59
+ attribute = request.params[resource].keys.first
60
+ value = request.params[resource][attribute]
61
+
62
+ if (defined?(::ActiveRecord::Base) && klass < ::ActiveRecord::Base)
63
+ middleware_klass = WaNew::ClientValidate::ActiveRecord::Middleware
64
+ end
65
+
66
+ middleware_klass.is_unique?(klass, attribute, value, request.params)
67
+ end
68
+
69
+ def extract_resource
70
+ parent_key = (request.params.keys - IGNORE_PARAMS).first
71
+ end
72
+ end
73
+
74
+ end
75
+
76
+ class Engine < ::Rails::Engine
77
+ config.app_middleware.use WaNew::ClientValidate::Middleware::Validators
78
+ end
79
+
80
+ end
81
+
@@ -0,0 +1,5 @@
1
+ module WaNew
2
+ module ClientValidate
3
+ VERSION = "0.0.11"
4
+ end
5
+ end
@@ -0,0 +1,12 @@
1
+ # ClientValidate
2
+ module WaNew
3
+ module ClientValidate
4
+ end
5
+ end
6
+
7
+
8
+ require 'wanew/client_validate/action_view'
9
+ require 'wanew/client_validate/active_model'
10
+ require 'wanew/client_validate/active_record'
11
+ require 'wanew/client_validate/middleware'
12
+
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: wanew_client_validate
3
+ version: !ruby/object:Gem::Version
4
+ hash: 9
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 11
10
+ version: 0.0.11
11
+ platform: ruby
12
+ authors:
13
+ - wanliu corporation
14
+ - hysios
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2011-05-31 00:00:00 +08:00
20
+ default_executable:
21
+ dependencies: []
22
+
23
+ description: Client Validate mainly appiled for WaNew Engine in the browser client side validate utils
24
+ email:
25
+ - hysios@gmail.com
26
+ executables: []
27
+
28
+ extensions: []
29
+
30
+ extra_rdoc_files: []
31
+
32
+ files:
33
+ - lib/wanew/client_validate/action_view/form_builder.rb
34
+ - lib/wanew/client_validate/action_view/form_helper.rb
35
+ - lib/wanew/client_validate/action_view.rb
36
+ - lib/wanew/client_validate/active_model/validator.rb
37
+ - lib/wanew/client_validate/active_model/validators.rb
38
+ - lib/wanew/client_validate/active_model.rb
39
+ - lib/wanew/client_validate/active_record/middleware.rb
40
+ - lib/wanew/client_validate/active_record/uniqueness.rb
41
+ - lib/wanew/client_validate/active_record.rb
42
+ - lib/wanew/client_validate/middleware.rb
43
+ - lib/wanew/client_validate/version.rb
44
+ - lib/wanew_client_validate.rb
45
+ - MIT-LICENSE
46
+ - init.rb
47
+ has_rdoc: true
48
+ homepage: http://github.com/hysios/client_validate
49
+ licenses: []
50
+
51
+ post_install_message:
52
+ rdoc_options: []
53
+
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ hash: 3
62
+ segments:
63
+ - 0
64
+ version: "0"
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ hash: 23
71
+ segments:
72
+ - 1
73
+ - 3
74
+ - 6
75
+ version: 1.3.6
76
+ requirements: []
77
+
78
+ rubyforge_project: wanew_client_validate
79
+ rubygems_version: 1.5.2
80
+ signing_key:
81
+ specification_version: 3
82
+ summary: WaNew Client Side Validations(like ClientSideValidations)
83
+ test_files: []
84
+