af-client_side_validations 3.1.4.af1

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.
Files changed (115) hide show
  1. data/client_side_validations.gemspec +34 -0
  2. data/lib/client_side_validations/action_view/form_builder.rb +160 -0
  3. data/lib/client_side_validations/action_view/form_helper.rb +92 -0
  4. data/lib/client_side_validations/action_view/form_tag_helper.rb +12 -0
  5. data/lib/client_side_validations/action_view.rb +14 -0
  6. data/lib/client_side_validations/active_model/acceptance.rb +10 -0
  7. data/lib/client_side_validations/active_model/exclusion.rb +15 -0
  8. data/lib/client_side_validations/active_model/format.rb +10 -0
  9. data/lib/client_side_validations/active_model/inclusion.rb +15 -0
  10. data/lib/client_side_validations/active_model/length.rb +24 -0
  11. data/lib/client_side_validations/active_model/numericality.rb +31 -0
  12. data/lib/client_side_validations/active_model/presence.rb +10 -0
  13. data/lib/client_side_validations/active_model.rb +60 -0
  14. data/lib/client_side_validations/active_record/middleware.rb +33 -0
  15. data/lib/client_side_validations/active_record/uniqueness.rb +28 -0
  16. data/lib/client_side_validations/active_record.rb +11 -0
  17. data/lib/client_side_validations/core_ext/range.rb +10 -0
  18. data/lib/client_side_validations/core_ext/regexp.rb +14 -0
  19. data/lib/client_side_validations/core_ext.rb +3 -0
  20. data/lib/client_side_validations/engine.rb +6 -0
  21. data/lib/client_side_validations/files.rb +8 -0
  22. data/lib/client_side_validations/formtastic.rb +21 -0
  23. data/lib/client_side_validations/middleware.rb +81 -0
  24. data/lib/client_side_validations/mongo_mapper/middleware.rb +20 -0
  25. data/lib/client_side_validations/mongo_mapper/uniqueness.rb +28 -0
  26. data/lib/client_side_validations/mongo_mapper.rb +9 -0
  27. data/lib/client_side_validations/mongoid/middleware.rb +20 -0
  28. data/lib/client_side_validations/mongoid/uniqueness.rb +28 -0
  29. data/lib/client_side_validations/mongoid.rb +9 -0
  30. data/lib/client_side_validations/simple_form.rb +24 -0
  31. data/lib/client_side_validations/version.rb +3 -0
  32. data/lib/client_side_validations.rb +13 -0
  33. data/lib/generators/client_side_validations/copy_asset_generator.rb +36 -0
  34. data/lib/generators/client_side_validations/install_generator.rb +45 -0
  35. data/lib/generators/templates/client_side_validations/README.rails.3.0 +6 -0
  36. data/lib/generators/templates/client_side_validations/README.rails.3.1 +7 -0
  37. data/lib/generators/templates/client_side_validations/initializer.rb +14 -0
  38. data/test/action_view/cases/helper.rb +176 -0
  39. data/test/action_view/cases/test_helpers.rb +666 -0
  40. data/test/action_view/cases/test_legacy_helpers.rb +217 -0
  41. data/test/action_view/models/comment.rb +35 -0
  42. data/test/action_view/models/post.rb +35 -0
  43. data/test/action_view/models.rb +3 -0
  44. data/test/active_model/cases/helper.rb +4 -0
  45. data/test/active_model/cases/test_acceptance_validator.rb +16 -0
  46. data/test/active_model/cases/test_base.rb +11 -0
  47. data/test/active_model/cases/test_confirmation_validator.rb +16 -0
  48. data/test/active_model/cases/test_exclusion_validator.rb +20 -0
  49. data/test/active_model/cases/test_format_validator.rb +21 -0
  50. data/test/active_model/cases/test_inclusion_validator.rb +21 -0
  51. data/test/active_model/cases/test_length_validator.rb +61 -0
  52. data/test/active_model/cases/test_numericality_validator.rb +46 -0
  53. data/test/active_model/cases/test_presence_validator.rb +16 -0
  54. data/test/active_model/cases/test_validations.rb +175 -0
  55. data/test/active_model/models/person.rb +17 -0
  56. data/test/active_record/cases/helper.rb +12 -0
  57. data/test/active_record/cases/test_base.rb +11 -0
  58. data/test/active_record/cases/test_middleware.rb +175 -0
  59. data/test/active_record/cases/test_uniqueness_validator.rb +50 -0
  60. data/test/active_record/models/guid.rb +7 -0
  61. data/test/active_record/models/user.rb +14 -0
  62. data/test/base_helper.rb +7 -0
  63. data/test/core_ext/cases/test_core_ext.rb +46 -0
  64. data/test/formtastic/cases/helper.rb +7 -0
  65. data/test/formtastic/cases/test_form_builder.rb +11 -0
  66. data/test/formtastic/cases/test_form_helper.rb +21 -0
  67. data/test/generators/cases/test_generators.rb +70 -0
  68. data/test/javascript/config.ru +3 -0
  69. data/test/javascript/public/test/callbacks/elementAfter.js +54 -0
  70. data/test/javascript/public/test/callbacks/elementBefore.js +54 -0
  71. data/test/javascript/public/test/callbacks/elementFail.js +70 -0
  72. data/test/javascript/public/test/callbacks/elementPass.js +70 -0
  73. data/test/javascript/public/test/callbacks/formAfter.js +45 -0
  74. data/test/javascript/public/test/callbacks/formBefore.js +45 -0
  75. data/test/javascript/public/test/callbacks/formFail.js +51 -0
  76. data/test/javascript/public/test/callbacks/formPass.js +50 -0
  77. data/test/javascript/public/test/form_builders/validateForm.js +66 -0
  78. data/test/javascript/public/test/form_builders/validateFormtastic.js +54 -0
  79. data/test/javascript/public/test/form_builders/validateNestedForm.js +66 -0
  80. data/test/javascript/public/test/form_builders/validateSimpleForm.js +57 -0
  81. data/test/javascript/public/test/settings.js +15 -0
  82. data/test/javascript/public/test/validateElement.js +209 -0
  83. data/test/javascript/public/test/validators/acceptance.js +42 -0
  84. data/test/javascript/public/test/validators/confirmation.js +25 -0
  85. data/test/javascript/public/test/validators/exclusion.js +41 -0
  86. data/test/javascript/public/test/validators/format.js +27 -0
  87. data/test/javascript/public/test/validators/inclusion.js +42 -0
  88. data/test/javascript/public/test/validators/length.js +76 -0
  89. data/test/javascript/public/test/validators/numericality.js +158 -0
  90. data/test/javascript/public/test/validators/presence.js +21 -0
  91. data/test/javascript/public/test/validators/uniqueness.js +107 -0
  92. data/test/javascript/public/vendor/jquery.metadata.js +122 -0
  93. data/test/javascript/public/vendor/qunit.css +196 -0
  94. data/test/javascript/public/vendor/qunit.js +1374 -0
  95. data/test/javascript/server.rb +84 -0
  96. data/test/javascript/views/index.erb +20 -0
  97. data/test/javascript/views/layout.erb +21 -0
  98. data/test/middleware/cases/helper.rb +18 -0
  99. data/test/middleware/cases/test_middleware.rb +8 -0
  100. data/test/mongo_mapper/cases/helper.rb +9 -0
  101. data/test/mongo_mapper/cases/test_base.rb +15 -0
  102. data/test/mongo_mapper/cases/test_middleware.rb +77 -0
  103. data/test/mongo_mapper/cases/test_uniqueness_validator.rb +50 -0
  104. data/test/mongo_mapper/models/magazine.rb +11 -0
  105. data/test/mongoid/cases/helper.rb +16 -0
  106. data/test/mongoid/cases/test_base.rb +15 -0
  107. data/test/mongoid/cases/test_middleware.rb +77 -0
  108. data/test/mongoid/cases/test_uniqueness_validator.rb +49 -0
  109. data/test/mongoid/models/book.rb +12 -0
  110. data/test/simple_form/cases/helper.rb +5 -0
  111. data/test/simple_form/cases/test_form_builder.rb +14 -0
  112. data/test/simple_form/cases/test_form_helper.rb +24 -0
  113. data/test/test_loader.rb +6 -0
  114. data/vendor/assets/javascripts/rails.validations.js +418 -0
  115. metadata +436 -0
@@ -0,0 +1,81 @@
1
+ # encoding: utf-8
2
+
3
+ require 'client_side_validations/core_ext'
4
+
5
+ module ClientSideValidations
6
+
7
+ module Middleware
8
+ class Validators
9
+ def initialize(app)
10
+ @app = app
11
+ end
12
+
13
+ def call(env)
14
+ case env['PATH_INFO']
15
+ when %r{\/validators\/(\w+)}
16
+ "::ClientSideValidations::Middleware::#{$1.camelize}".constantize.new(env).response
17
+ else
18
+ @app.call(env)
19
+ end
20
+ end
21
+ end
22
+
23
+ class Base
24
+ attr_accessor :request, :body, :status
25
+
26
+ def initialize(env)
27
+ self.body = ''
28
+ self.status = 200
29
+ self.request = ActionDispatch::Request.new(env)
30
+ end
31
+
32
+ def response
33
+ [status, {'Content-Type' => content_type, 'Content-Length' => body.length.to_s}, [body]]
34
+ end
35
+
36
+ def content_type
37
+ 'application/json'
38
+ end
39
+ end
40
+
41
+ class Uniqueness < Base
42
+ IGNORE_PARAMS = %w{case_sensitive id scope}
43
+
44
+ def response
45
+ if is_unique?
46
+ self.status = 404
47
+ self.body = 'true'
48
+ else
49
+ self.status = 200
50
+ self.body = 'false'
51
+ end
52
+ super
53
+ end
54
+
55
+ private
56
+
57
+ def is_unique?
58
+ resource = extract_resource
59
+ klass = resource.classify.constantize
60
+ attribute = request.params[resource].keys.first
61
+ value = request.params[resource][attribute]
62
+
63
+ if (defined?(::ActiveRecord::Base) && klass < ::ActiveRecord::Base)
64
+ middleware_klass = ClientSideValidations::ActiveRecord::Middleware
65
+ elsif (defined?(::Mongoid::Document) && klass.included_modules.include?(::Mongoid::Document))
66
+ middleware_klass = ClientSideValidations::Mongoid::Middleware
67
+ elsif (defined?(::MongoMapper::Document) && klass.included_modules.include?(::MongoMapper::Document))
68
+ middleware_klass = ClientSideValidations::MongoMapper::Middleware
69
+ end
70
+
71
+ middleware_klass.is_unique?(klass, attribute, value, request.params)
72
+ end
73
+
74
+ def extract_resource
75
+ parent_key = (request.params.keys - IGNORE_PARAMS).first
76
+ end
77
+ end
78
+ end
79
+
80
+ end
81
+
@@ -0,0 +1,20 @@
1
+ module ClientSideValidations::MongoMapper
2
+ class Middleware
3
+
4
+ # Still need to handle embedded documents
5
+ def self.is_unique?(klass, attribute, value, params)
6
+ if params[:case_sensitive] == 'false'
7
+ value = Regexp.new("^#{Regexp.escape(value.to_s)}$", Regexp::IGNORECASE)
8
+ end
9
+
10
+ criteria = klass.where(attribute => value)
11
+ criteria = criteria.where(:_id => {'$ne' => BSON::ObjectId(params[:id])}) if params[:id]
12
+
13
+ (params[:scope] || {}).each do |key, value|
14
+ criteria = criteria.where(key => value)
15
+ end
16
+
17
+ !criteria.exists?
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,28 @@
1
+ module ClientSideValidations::MongoMapper
2
+ module Uniqueness
3
+ def client_side_hash(model, attribute)
4
+ hash = {}
5
+ hash[:message] = model.errors.generate_message(attribute, message_type, options.except(:scope))
6
+ hash[:case_sensitive] = options[:case_sensitive] if options.key?(:case_sensitive)
7
+ hash[:id] = model.id unless model.new_record?
8
+ if options.key?(:scope) && options[:scope].present?
9
+ hash[:scope] = Array.wrap(options[:scope]).inject({}) do |scope_hash, scope_item|
10
+ scope_hash.merge!(scope_item => model.send(scope_item))
11
+ end
12
+ end
13
+
14
+ unless model.class.name.demodulize == model.class.name
15
+ hash[:class] = model.class.name.underscore
16
+ end
17
+
18
+ hash
19
+ end
20
+
21
+ private
22
+
23
+ def message_type
24
+ :taken
25
+ end
26
+ end
27
+ end
28
+
@@ -0,0 +1,9 @@
1
+ require 'client_side_validations/active_model'
2
+ require 'client_side_validations/mongo_mapper/middleware'
3
+
4
+ %w{uniqueness}.each do |validator|
5
+ require "client_side_validations/mongo_mapper/#{validator}"
6
+ validator.capitalize!
7
+ eval "MongoMapper::Plugins::Validations::#{validator}Validator.send(:include, ClientSideValidations::MongoMapper::#{validator})"
8
+ end
9
+
@@ -0,0 +1,20 @@
1
+ module ClientSideValidations::Mongoid
2
+ class Middleware
3
+
4
+ # Still need to handle embedded documents
5
+ def self.is_unique?(klass, attribute, value, params)
6
+ if params[:case_sensitive] == 'false'
7
+ value = Regexp.new("^#{Regexp.escape(value.to_s)}$", Regexp::IGNORECASE)
8
+ end
9
+
10
+ criteria = klass.where(attribute => value)
11
+ criteria = criteria.where(:_id => {'$ne' => BSON::ObjectId(params[:id])}) if params[:id]
12
+
13
+ (params[:scope] || {}).each do |key, value|
14
+ criteria = criteria.where(key => value)
15
+ end
16
+
17
+ !criteria.exists?
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,28 @@
1
+ module ClientSideValidations::Mongoid
2
+ module Uniqueness
3
+ def client_side_hash(model, attribute)
4
+ hash = {}
5
+ hash[:message] = model.errors.generate_message(attribute, message_type, options.except(:scope))
6
+ hash[:case_sensitive] = options[:case_sensitive] if options.key?(:case_sensitive)
7
+ hash[:id] = model.id unless model.new_record?
8
+ if options.key?(:scope) && options[:scope].present?
9
+ hash[:scope] = Array.wrap(options[:scope]).inject({}) do |scope_hash, scope_item|
10
+ scope_hash.merge!(scope_item => model.send(scope_item))
11
+ end
12
+ end
13
+
14
+ unless model.class.name.demodulize == model.class.name
15
+ hash[:class] = model.class.name.underscore
16
+ end
17
+
18
+ hash
19
+ end
20
+
21
+ private
22
+
23
+ def message_type
24
+ :taken
25
+ end
26
+ end
27
+ end
28
+
@@ -0,0 +1,9 @@
1
+ require 'client_side_validations/active_model'
2
+ require 'client_side_validations/mongoid/middleware'
3
+
4
+ %w{uniqueness}.each do |validator|
5
+ require "client_side_validations/mongoid/#{validator}"
6
+ validator.capitalize!
7
+ eval "Mongoid::Validations::#{validator}Validator.send(:include, ClientSideValidations::Mongoid::#{validator})"
8
+ end
9
+
@@ -0,0 +1,24 @@
1
+ module ClientSideValidations
2
+ module SimpleForm
3
+ module FormBuilder
4
+
5
+ def self.included(base)
6
+ base.class_eval do
7
+ def self.client_side_form_settings(options, form_helper)
8
+ {
9
+ :type => self.to_s,
10
+ :error_class => ::SimpleForm.error_class,
11
+ :error_tag => ::SimpleForm.error_tag,
12
+ :wrapper_error_class => ::SimpleForm.wrapper_error_class,
13
+ :wrapper_tag => ::SimpleForm.wrapper_tag
14
+ }
15
+ end
16
+ end
17
+ end
18
+
19
+ end
20
+ end
21
+ end
22
+
23
+ SimpleForm::FormBuilder.send(:include, ClientSideValidations::SimpleForm::FormBuilder)
24
+
@@ -0,0 +1,3 @@
1
+ module ClientSideValidations
2
+ VERSION = '3.1.4.af1'
3
+ end
@@ -0,0 +1,13 @@
1
+ module ClientSideValidations
2
+ end
3
+
4
+ require 'client_side_validations/active_model' if defined?(::ActiveModel)
5
+ require 'client_side_validations/active_record' if defined?(::ActiveRecord)
6
+ require 'client_side_validations/mongoid' if defined?(::Mongoid)
7
+ require 'client_side_validations/mongo_mapper' if defined?(::MongoMapper)
8
+ require 'client_side_validations/action_view' if defined?(::ActionView)
9
+ if defined?(::Rails)
10
+ require 'client_side_validations/middleware'
11
+ require 'client_side_validations/engine'
12
+ end
13
+
@@ -0,0 +1,36 @@
1
+ module ClientSideValidations
2
+ module Generators
3
+ class CopyAssetGenerator < Rails::Generators::Base
4
+ source_root File.expand_path('../../../../vendor/assets/javascripts', __FILE__)
5
+
6
+ private
7
+
8
+ def self.asset_pipeline_enabled?
9
+ (Rails.configuration.respond_to?(:assets) ? (Rails.configuration.assets || {}) : {})[:enabled]
10
+ end
11
+
12
+ def asset_pipeline_enabled?
13
+ self.class.asset_pipeline_enabled?
14
+ end
15
+
16
+ public
17
+
18
+ if asset_pipeline_enabled?
19
+ desc 'Creates a ClientSideValidations initializer and copies rails.validations.js to app/assets/javascripts.'
20
+ else
21
+ desc 'Creates a ClientSideValidations initializer and copies rails.validations.js to public/javascripts.'
22
+ end
23
+
24
+ def copy_javascript_asset
25
+ if asset_pipeline_enabled?
26
+ destination = 'app/assets/javascripts'
27
+ else
28
+ destination = 'public/javascripts'
29
+ end
30
+
31
+ copy_file 'rails.validations.js', "#{destination}/rails.validations.js"
32
+ end
33
+ end
34
+ end
35
+ end
36
+
@@ -0,0 +1,45 @@
1
+ module ClientSideValidations
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+ source_root File.expand_path('../../templates/client_side_validations', __FILE__)
5
+
6
+ private
7
+
8
+ def self.asset_pipeline_enabled?
9
+ (Rails.configuration.respond_to?(:assets) ? (Rails.configuration.assets || {}) : {})[:enabled]
10
+ end
11
+
12
+ def asset_pipeline_enabled?
13
+ self.class.asset_pipeline_enabled?
14
+ end
15
+
16
+ public
17
+
18
+ if asset_pipeline_enabled?
19
+ desc 'Creates a ClientSideValidations initializer.'
20
+ else
21
+ desc 'Creates a ClientSideValidations initializer and copies rails.validations.js to public/javascripts.'
22
+ end
23
+
24
+ def copy_initializer
25
+ copy_file 'initializer.rb', 'config/initializers/client_side_validations.rb'
26
+ end
27
+
28
+ def copy_javascript_asset
29
+ unless asset_pipeline_enabled?
30
+ copy_file '../../../../vendor/assets/javascripts/rails.validations.js', 'public/javascripts/rails.validations.js'
31
+ end
32
+ end
33
+
34
+ def show_readme
35
+ if Rails.version >= '3.1'
36
+ readme 'README.rails.3.1' if behavior == :invoke
37
+ else
38
+ readme 'README.rails.3.0' if behavior == :invoke
39
+ end
40
+ end
41
+
42
+ end
43
+ end
44
+ end
45
+
@@ -0,0 +1,6 @@
1
+ *********************
2
+ ClientSideValidations
3
+ *********************
4
+
5
+ Client Side Validations only works with jQuery.
6
+ You'll need to include jQuery in your layout file before you include 'rails.validations.js'
@@ -0,0 +1,7 @@
1
+ *********************
2
+ ClientSideValidations
3
+ *********************
4
+
5
+ In your app/assets/javascripts/application.js file add the following:
6
+
7
+ //= require rails.validations
@@ -0,0 +1,14 @@
1
+ # ClientSideValidations Initializer
2
+
3
+ require 'client_side_validations/simple_form' if defined?(::SimpleForm)
4
+ require 'client_side_validations/formtastic' if defined?(::Formtastic)
5
+
6
+ # Uncomment the following block if you want each input field to have the validation messages attached.
7
+ # ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
8
+ # unless html_tag =~ /^<label/
9
+ # %{<div class="field_with_errors">#{html_tag}<label for="#{instance.send(:tag_id)}" class="message">#{instance.error_message.first}</label></div>}.html_safe
10
+ # else
11
+ # %{<div class="field_with_errors">#{html_tag}</div>}.html_safe
12
+ # end
13
+ # end
14
+
@@ -0,0 +1,176 @@
1
+ require 'base_helper'
2
+ require 'action_view'
3
+ require 'action_view/template'
4
+ require 'action_view/models'
5
+ require 'client_side_validations/action_view'
6
+
7
+ module ActionController
8
+ class Base
9
+ include ActionDispatch::Routing::RouteSet.new.url_helpers
10
+ end
11
+ end
12
+
13
+ module ActionViewTestSetup
14
+ include ::ClientSideValidations::ActionView::Helpers::FormHelper
15
+ include ::ClientSideValidations::ActionView::Helpers::FormTagHelper
16
+
17
+ def form_for(*)
18
+ @output_buffer = super
19
+ end
20
+
21
+ Routes = ActionDispatch::Routing::RouteSet.new
22
+ Routes.draw do
23
+ resources :posts do
24
+ resources :comments
25
+ end
26
+ end
27
+
28
+ def _routes
29
+ Routes
30
+ end
31
+
32
+ include Routes.url_helpers
33
+
34
+ def setup
35
+ super
36
+
37
+ # Create "label" locale for testing I18n label helpers
38
+ I18n.backend.store_translations 'label', {
39
+ :activemodel => {
40
+ :attributes => {
41
+ :post => {
42
+ :cost => "Total cost"
43
+ }
44
+ }
45
+ },
46
+ :helpers => {
47
+ :label => {
48
+ :post => {
49
+ :body => "Write entire text here"
50
+ }
51
+ }
52
+ }
53
+ }
54
+
55
+ # Create "submit" locale for testing I18n submit helpers
56
+ I18n.backend.store_translations 'submit', {
57
+ :helpers => {
58
+ :submit => {
59
+ :create => 'Create %{model}',
60
+ :update => 'Confirm %{model} changes',
61
+ :submit => 'Save changes',
62
+ :another_post => {
63
+ :update => 'Update your %{model}'
64
+ }
65
+ }
66
+ }
67
+ }
68
+
69
+ @post = Post.new
70
+ @comment = Comment.new
71
+ def @post.errors()
72
+ Class.new{
73
+ def [](field); field == "author_name" ? ["can't be empty"] : [] end
74
+ def empty?() false end
75
+ def count() 1 end
76
+ def full_messages() [ "Author name can't be empty" ] end
77
+ }.new
78
+ end
79
+ def @post.id; 123; end
80
+ def @post.id_before_type_cast; 123; end
81
+ def @post.to_param; '123'; end
82
+
83
+ @post.persisted = true
84
+ @post.title = "Hello World"
85
+ @post.author_name = ""
86
+ @post.body = "Back to the hill and over it again!"
87
+ @post.secret = 1
88
+ @post.written_on = Date.new(2004, 6, 15)
89
+
90
+ if defined?(ActionView::OutputFlow)
91
+ @view_flow = ActionView::OutputFlow.new
92
+ else
93
+ @_content_for = Hash.new { |h,k| h[k] = ActiveSupport::SafeBuffer.new }
94
+ end
95
+ end
96
+
97
+ def snowman(method = nil)
98
+ txt = %{<div style="margin:0;padding:0;display:inline">}
99
+ txt << %{<input name="utf8" type="hidden" value="&#x2713;" />}
100
+ txt << %{<input name="_method" type="hidden" value="#{method}" />} if method
101
+ txt << %{</div>}
102
+ end
103
+
104
+ def form_text(action = "http://www.example.com", id = nil, html_class = nil, remote = nil, validators = nil, file = nil)
105
+ txt = %{<form accept-charset="UTF-8" action="#{action}"}
106
+ txt << %{ data-remote="true"} if remote
107
+ txt << %{ class="#{html_class}"} if html_class
108
+ txt << %{ data-validate="true"} if validators
109
+ txt << %{ enctype="multipart/form-data"} if file
110
+ txt << %{ id="#{id}"} if id
111
+ txt << %{ method="post"}
112
+ txt << %{ novalidate="novalidate"} if validators
113
+ txt << %{>}
114
+ end
115
+
116
+ def whole_form(action = "http://www.example.com", id = nil, html_class = nil, options = nil)
117
+ contents = block_given? ? yield : ""
118
+
119
+ if options.is_a?(Hash)
120
+ method, remote, validators, file = options.values_at(:method, :remote, :validators, :file)
121
+ else
122
+ method = options
123
+ end
124
+
125
+ html = form_text(action, id, html_class, remote, validators, file) + snowman(method) + (contents || "") + "</form>"
126
+
127
+ if options.is_a?(Hash) && options[:validators]
128
+ build_script_tag(html, id, options[:validators])
129
+ else
130
+ html
131
+ end
132
+ end
133
+
134
+ def build_script_tag(html, id, validators)
135
+ (html || "") + %Q{<script>window['#{id}'] = #{client_side_form_settings_helper.merge(:validators => validators).to_json};</script>}
136
+ end
137
+
138
+ protected
139
+ def comments_path(post)
140
+ "/posts/#{post.id}/comments"
141
+ end
142
+ alias_method :post_comments_path, :comments_path
143
+
144
+ def comment_path(post, comment)
145
+ "/posts/#{post.id}/comments/#{comment.id}"
146
+ end
147
+ alias_method :post_comment_path, :comment_path
148
+
149
+ def admin_comments_path(post)
150
+ "/admin/posts/#{post.id}/comments"
151
+ end
152
+ alias_method :admin_post_comments_path, :admin_comments_path
153
+
154
+ def admin_comment_path(post, comment)
155
+ "/admin/posts/#{post.id}/comments/#{comment.id}"
156
+ end
157
+ alias_method :admin_post_comment_path, :admin_comment_path
158
+
159
+ def posts_path
160
+ "/posts"
161
+ end
162
+
163
+ def post_path(post, options = {})
164
+ if options[:format]
165
+ "/posts/#{post.id}.#{options[:format]}"
166
+ else
167
+ "/posts/#{post.id}"
168
+ end
169
+ end
170
+
171
+ def protect_against_forgery?
172
+ false
173
+ end
174
+
175
+ end
176
+