visionmedia-dm-forms 0.0.2 → 0.0.3
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/History.rdoc +4 -0
- data/Manifest +19 -16
- data/README.rdoc +4 -33
- data/Rakefile +6 -4
- data/Todo.rdoc +13 -15
- data/dm-forms.gemspec +7 -4
- data/examples/benchmarks.rb +26 -110
- data/examples/login.rb +20 -0
- data/lib/dm-forms.rb +5 -6
- data/lib/dm-forms/base.rb +115 -0
- data/lib/dm-forms/core_ext.rb +27 -22
- data/lib/dm-forms/helpers.rb +83 -0
- data/lib/dm-forms/mixins.rb +8 -0
- data/lib/dm-forms/mixins/descriptions.rb +18 -0
- data/lib/dm-forms/mixins/errors.rb +0 -0
- data/lib/dm-forms/mixins/labels.rb +16 -0
- data/lib/dm-forms/mixins/wrappers.rb +26 -0
- data/lib/dm-forms/tag.rb +67 -134
- data/lib/dm-forms/version.rb +1 -4
- data/spec/functional/helpers_spec.rb +186 -0
- data/spec/functional/mixins/descriptions_spec.rb +19 -0
- data/spec/functional/mixins/labels_spec.rb +19 -0
- data/spec/functional/mixins/wrappers_spec.rb +21 -0
- data/spec/functional/tag_spec.rb +33 -41
- data/spec/integration/datamapper_spec.rb +73 -45
- data/spec/spec_helper.rb +5 -7
- data/tasks/spec.rake +5 -0
- metadata +42 -22
- data/examples/datamapper.rb +0 -37
- data/examples/elements.rb +0 -31
- data/examples/haml.rb +0 -21
- data/examples/login.haml +0 -4
- data/lib/dm-forms/elements.rb +0 -210
- data/lib/dm-forms/model_elements.rb +0 -33
- data/spec/functional/core_ext_spec.rb +0 -56
- data/spec/functional/elements_spec.rb +0 -209
- data/spec/integration/haml_spec.rb +0 -29
data/History.rdoc
CHANGED
data/Manifest
CHANGED
@@ -1,27 +1,30 @@
|
|
1
|
-
|
2
|
-
Manifest
|
3
|
-
README.rdoc
|
4
|
-
Rakefile
|
5
|
-
Todo.rdoc
|
1
|
+
dm-forms.gemspec
|
6
2
|
examples/benchmarks.rb
|
7
|
-
examples/
|
8
|
-
|
9
|
-
|
10
|
-
examples/login.haml
|
11
|
-
lib/dm-forms.rb
|
3
|
+
examples/login.rb
|
4
|
+
History.rdoc
|
5
|
+
lib/dm-forms/base.rb
|
12
6
|
lib/dm-forms/core_ext.rb
|
13
|
-
lib/dm-forms/
|
14
|
-
lib/dm-forms/
|
7
|
+
lib/dm-forms/helpers.rb
|
8
|
+
lib/dm-forms/mixins/descriptions.rb
|
9
|
+
lib/dm-forms/mixins/errors.rb
|
10
|
+
lib/dm-forms/mixins/labels.rb
|
11
|
+
lib/dm-forms/mixins/wrappers.rb
|
12
|
+
lib/dm-forms/mixins.rb
|
15
13
|
lib/dm-forms/tag.rb
|
16
14
|
lib/dm-forms/version.rb
|
17
|
-
|
18
|
-
|
15
|
+
lib/dm-forms.rb
|
16
|
+
Manifest
|
17
|
+
Rakefile
|
18
|
+
README.rdoc
|
19
|
+
spec/functional/helpers_spec.rb
|
20
|
+
spec/functional/mixins/descriptions_spec.rb
|
21
|
+
spec/functional/mixins/labels_spec.rb
|
22
|
+
spec/functional/mixins/wrappers_spec.rb
|
19
23
|
spec/functional/tag_spec.rb
|
20
24
|
spec/integration/datamapper_spec.rb
|
21
|
-
spec/integration/haml_spec.rb
|
22
25
|
spec/spec_helper.rb
|
23
26
|
tasks/benchmarks.rake
|
24
27
|
tasks/docs.rake
|
25
28
|
tasks/gemspec.rake
|
26
29
|
tasks/spec.rake
|
27
|
-
|
30
|
+
Todo.rdoc
|
data/README.rdoc
CHANGED
@@ -3,44 +3,15 @@
|
|
3
3
|
|
4
4
|
DataMapper model form generation.
|
5
5
|
|
6
|
-
== Features
|
7
|
-
|
8
|
-
*
|
9
|
-
* Fast; over 1000 elements in 0.1 seconds (rake benchmark)
|
10
|
-
* Error reporting
|
11
|
-
* Handles restful HTTP verbs
|
12
|
-
* Provides low-level form elements uncoupled from DataMapper
|
13
|
-
|
14
|
-
== Examples:
|
15
|
-
|
16
|
-
Pretend in a magical world we have a User model, and only the email is valid while we are updating.
|
17
|
-
Based on the situation above, the form would render similar to the markup beneath the
|
18
|
-
example.
|
19
|
-
|
20
|
-
errors_for @user
|
21
|
-
form_for @user, :action => '/user' do |f|
|
22
|
-
f.textfield :name, :label => 'Name'
|
23
|
-
f.textfield :email, :label => 'Email'
|
24
|
-
f.submit :op, :value => 'Update'
|
25
|
-
end
|
26
|
-
|
27
|
-
<ul class="messages error">
|
28
|
-
<li>Name has an invalid format</li>
|
29
|
-
</ul>
|
30
|
-
<form action="/user" method="post" id="form-user">
|
31
|
-
<input type="hidden" name="_method" value="put" />
|
32
|
-
<label for="name">Name:</label>
|
33
|
-
<input type="textfield" class="error form-textfield form-name" name="name" />
|
34
|
-
<label for="email">Email:</label>
|
35
|
-
<input type="textfield" class="form-textfield form-email" name="email" />
|
36
|
-
<input type="submit" class="form-submit form-op" value="Update" name="op" />
|
37
|
-
</form>
|
6
|
+
== Features
|
7
|
+
|
8
|
+
* Coming soon
|
38
9
|
|
39
10
|
== License:
|
40
11
|
|
41
12
|
(The MIT License)
|
42
13
|
|
43
|
-
Copyright (c) 2008 TJ Holowaychuk
|
14
|
+
Copyright (c) 2008-2009 TJ Holowaychuk <tj@vision-media.ca>
|
44
15
|
|
45
16
|
Permission is hereby granted, free of charge, to any person obtaining
|
46
17
|
a copy of this software and associated documentation files (the
|
data/Rakefile
CHANGED
@@ -2,15 +2,17 @@
|
|
2
2
|
require 'rubygems'
|
3
3
|
require 'rake'
|
4
4
|
require 'echoe'
|
5
|
-
|
5
|
+
$:.unshift 'lib'
|
6
|
+
require 'dm-forms'
|
6
7
|
|
7
|
-
Echoe.new
|
8
|
+
Echoe.new "dm-forms", DataMapper::Form::VERSION do |p|
|
8
9
|
p.author = "TJ Holowaychuk"
|
9
10
|
p.email = "tj@vision-media.ca"
|
10
11
|
p.summary = "DataMapper model form generation"
|
11
12
|
p.url = "http://github.com/visionmedia/dm-forms"
|
12
|
-
p.runtime_dependencies
|
13
|
-
p.
|
13
|
+
p.runtime_dependencies << 'dm-core'
|
14
|
+
p.runtime_dependencies << 'visionmedia-rext'
|
15
|
+
p.development_dependencies << 'rspec_hpricot_matchers'
|
14
16
|
end
|
15
17
|
|
16
18
|
Dir['tasks/**/*.rake'].sort.each { |lib| load lib }
|
data/Todo.rdoc
CHANGED
@@ -1,24 +1,22 @@
|
|
1
1
|
|
2
2
|
== Major:
|
3
3
|
|
4
|
-
*
|
5
|
-
*
|
6
|
-
*
|
7
|
-
*
|
8
|
-
*
|
9
|
-
*
|
10
|
-
*
|
11
|
-
*
|
12
|
-
*
|
13
|
-
*
|
14
|
-
*
|
15
|
-
*
|
16
|
-
* perform some indenting (or all but make it optional)
|
17
|
-
* increase performance
|
18
|
-
* preview rdoc / finish documenting ...
|
4
|
+
* major refactor with processing of elements since some allow contents param, and some do not etc
|
5
|
+
* get rid of origin.buffer..what is merbs technique?
|
6
|
+
* select optgroups
|
7
|
+
* use stack (array) method for contexts ... cleaner than manual toggling
|
8
|
+
* allow explicit context names, not just auto-generated from class names
|
9
|
+
* view merb form helper specs to see what was missed
|
10
|
+
* abstract ORM ? rename from dm-forms ... have ORM mixins
|
11
|
+
* only one context so dont use all those methods? just capture with optional builder base?
|
12
|
+
* self closing tags auto self-close to maximize mixin DRYness
|
13
|
+
* Make sure othe frameworks can plug in their functionality
|
14
|
+
* documentation per method generated
|
15
|
+
* better naming conventions / refactor / release
|
19
16
|
|
20
17
|
== Minor:
|
21
18
|
|
19
|
+
* have these optional as mixins?
|
22
20
|
* Aggregate / faux elements ...
|
23
21
|
* date_field :bday, :format => 'YYYY-MM-DD', :value => '1987-05-25'
|
24
22
|
|
data/dm-forms.gemspec
CHANGED
@@ -2,15 +2,15 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{dm-forms}
|
5
|
-
s.version = "0.0.
|
5
|
+
s.version = "0.0.3"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["TJ Holowaychuk"]
|
9
|
-
s.date = %q{2009-
|
9
|
+
s.date = %q{2009-03-23}
|
10
10
|
s.description = %q{DataMapper model form generation}
|
11
11
|
s.email = %q{tj@vision-media.ca}
|
12
|
-
s.extra_rdoc_files = ["
|
13
|
-
s.files = ["
|
12
|
+
s.extra_rdoc_files = ["lib/dm-forms/base.rb", "lib/dm-forms/core_ext.rb", "lib/dm-forms/helpers.rb", "lib/dm-forms/mixins/descriptions.rb", "lib/dm-forms/mixins/errors.rb", "lib/dm-forms/mixins/labels.rb", "lib/dm-forms/mixins/wrappers.rb", "lib/dm-forms/mixins.rb", "lib/dm-forms/tag.rb", "lib/dm-forms/version.rb", "lib/dm-forms.rb", "README.rdoc", "tasks/benchmarks.rake", "tasks/docs.rake", "tasks/gemspec.rake", "tasks/spec.rake"]
|
13
|
+
s.files = ["dm-forms.gemspec", "examples/benchmarks.rb", "examples/login.rb", "History.rdoc", "lib/dm-forms/base.rb", "lib/dm-forms/core_ext.rb", "lib/dm-forms/helpers.rb", "lib/dm-forms/mixins/descriptions.rb", "lib/dm-forms/mixins/errors.rb", "lib/dm-forms/mixins/labels.rb", "lib/dm-forms/mixins/wrappers.rb", "lib/dm-forms/mixins.rb", "lib/dm-forms/tag.rb", "lib/dm-forms/version.rb", "lib/dm-forms.rb", "Manifest", "Rakefile", "README.rdoc", "spec/functional/helpers_spec.rb", "spec/functional/mixins/descriptions_spec.rb", "spec/functional/mixins/labels_spec.rb", "spec/functional/mixins/wrappers_spec.rb", "spec/functional/tag_spec.rb", "spec/integration/datamapper_spec.rb", "spec/spec_helper.rb", "tasks/benchmarks.rake", "tasks/docs.rake", "tasks/gemspec.rake", "tasks/spec.rake", "Todo.rdoc"]
|
14
14
|
s.has_rdoc = true
|
15
15
|
s.homepage = %q{http://github.com/visionmedia/dm-forms}
|
16
16
|
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Dm-forms", "--main", "README.rdoc"]
|
@@ -25,13 +25,16 @@ Gem::Specification.new do |s|
|
|
25
25
|
|
26
26
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
27
27
|
s.add_runtime_dependency(%q<dm-core>, [">= 0"])
|
28
|
+
s.add_runtime_dependency(%q<visionmedia-rext>, [">= 0"])
|
28
29
|
s.add_development_dependency(%q<rspec_hpricot_matchers>, [">= 0"])
|
29
30
|
else
|
30
31
|
s.add_dependency(%q<dm-core>, [">= 0"])
|
32
|
+
s.add_dependency(%q<visionmedia-rext>, [">= 0"])
|
31
33
|
s.add_dependency(%q<rspec_hpricot_matchers>, [">= 0"])
|
32
34
|
end
|
33
35
|
else
|
34
36
|
s.add_dependency(%q<dm-core>, [">= 0"])
|
37
|
+
s.add_dependency(%q<visionmedia-rext>, [">= 0"])
|
35
38
|
s.add_dependency(%q<rspec_hpricot_matchers>, [">= 0"])
|
36
39
|
end
|
37
40
|
end
|
data/examples/benchmarks.rb
CHANGED
@@ -1,118 +1,34 @@
|
|
1
1
|
|
2
|
-
|
3
|
-
require 'dm-forms'
|
4
|
-
require 'benchmark'
|
5
|
-
require 'dm-core'
|
6
|
-
require 'dm-validations'
|
7
|
-
DataMapper.setup :default, 'sqlite3::memory:'
|
8
|
-
include DataMapper::Form::ModelElements
|
2
|
+
require File.dirname(__FILE__) + '/../lib/dm-forms'
|
9
3
|
|
10
|
-
|
11
|
-
|
12
|
-
#++
|
4
|
+
require 'rubygems'
|
5
|
+
require 'rgauge'
|
13
6
|
|
14
|
-
|
15
|
-
include DataMapper::Resource
|
16
|
-
property :id, Serial
|
17
|
-
property :name, String, :format => /^[\w]+$/
|
18
|
-
property :email, String, :format => :email_address
|
19
|
-
end
|
20
|
-
|
21
|
-
DataMapper.auto_migrate!
|
22
|
-
|
23
|
-
$user = User.new :name => 'tj', :email => 'invalid email@lame.com'
|
24
|
-
|
25
|
-
#--
|
26
|
-
# Benchmarks
|
27
|
-
#++
|
28
|
-
|
29
|
-
puts
|
30
|
-
puts 'Single element'
|
31
|
-
Benchmark.bm(25) do |x|
|
32
|
-
x.report("10 elements") {
|
33
|
-
10.times do
|
34
|
-
textarea :comments, :value => 'Enter your comments here', :label => 'Comments:', :required => true
|
35
|
-
end
|
36
|
-
}
|
37
|
-
x.report("100 elements") {
|
38
|
-
100.times do
|
39
|
-
textarea :comments, :value => 'Enter your comments here', :label => 'Comments:', :required => true
|
40
|
-
end
|
41
|
-
}
|
42
|
-
x.report("1000 elements") {
|
43
|
-
1000.times do
|
44
|
-
textarea :comments, :value => 'Enter your comments here', :label => 'Comments:', :required => true
|
45
|
-
end
|
46
|
-
}
|
47
|
-
end
|
7
|
+
include DataMapper::Form::Helpers
|
48
8
|
|
49
|
-
|
50
|
-
|
51
|
-
Benchmark.bm(25) do |x|
|
52
|
-
x.report("10 elements") {
|
53
|
-
5.times do
|
54
|
-
fieldset :comments do |f|
|
55
|
-
f.textarea :comments, :value => 'Enter your comments here', :label => 'Comments:', :required => true
|
56
|
-
end
|
57
|
-
end
|
58
|
-
}
|
59
|
-
x.report("100 elements") {
|
60
|
-
50.times do
|
61
|
-
fieldset :comments do |f|
|
62
|
-
f.textarea :comments, :value => 'Enter your comments here', :label => 'Comments:', :required => true
|
63
|
-
end
|
64
|
-
end
|
65
|
-
}
|
66
|
-
x.report("1000 elements") {
|
67
|
-
500.times do
|
68
|
-
fieldset :comments do |f|
|
69
|
-
f.textarea :comments, :value => 'Enter your comments here', :label => 'Comments:', :required => true
|
70
|
-
end
|
71
|
-
end
|
72
|
-
}
|
9
|
+
def params
|
10
|
+
Hash.new { |h, k| k }
|
73
11
|
end
|
12
|
+
public :params
|
74
13
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
f.textfield :name, :label => 'Username', :required => true
|
82
|
-
f.textfield :email, :label => 'Email', :required => true
|
83
|
-
f.textfield :pass, :label => 'Password', :required => true
|
84
|
-
f.submit :op, :value => 'Login'
|
14
|
+
benchmark 'Entire forms', :times => 400 do
|
15
|
+
report 'Login' do
|
16
|
+
form :action => '/login' do
|
17
|
+
textfield :name, :id => 'username'
|
18
|
+
textfield :pass, :id => 'password'
|
19
|
+
submit :value => 'Login'
|
85
20
|
end
|
86
|
-
|
21
|
+
end
|
87
22
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
f.fieldset :forums do |f|
|
101
|
-
f.textarea :signature, :label => 'Signature', :description => 'Enter a signature which will appear below your forum posts.'
|
102
|
-
end
|
103
|
-
f.submit :op, :value => 'Register'
|
104
|
-
end
|
105
|
-
}
|
106
|
-
end
|
107
|
-
|
108
|
-
puts
|
109
|
-
puts 'Entires form with #form_for'
|
110
|
-
Benchmark.bm(25) do |x|
|
111
|
-
x.report("User") {
|
112
|
-
form_for $user do |f|
|
113
|
-
f.textfield :name, :label => 'Username', :required => true
|
114
|
-
f.textfield :email, :label => 'Email', :required => true
|
115
|
-
f.submit :op, :value => 'Login'
|
116
|
-
end
|
117
|
-
}
|
118
|
-
end
|
23
|
+
DataMapper::Form::Base.send :include, DataMapper::Form::Labels
|
24
|
+
DataMapper::Form::Base.send :include, DataMapper::Form::Descriptions
|
25
|
+
DataMapper::Form::Base.send :include, DataMapper::Form::Wrappers
|
26
|
+
|
27
|
+
report 'Login with mixins' do
|
28
|
+
form :action => '/login' do
|
29
|
+
textfield :name, :id => 'username', :label => 'Username'
|
30
|
+
textfield :pass, :id => 'password', :label => 'Password', :description => 'Enter a valid password.'
|
31
|
+
submit :value => 'Login'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/examples/login.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
|
2
|
+
require File.dirname(__FILE__) + '/../lib/dm-forms'
|
3
|
+
|
4
|
+
include DataMapper::Form::Helpers
|
5
|
+
DataMapper::Form::Base.send :include, DataMapper::Form::Labels
|
6
|
+
DataMapper::Form::Base.send :include, DataMapper::Form::Descriptions
|
7
|
+
DataMapper::Form::Base.send :include, DataMapper::Form::Wrappers
|
8
|
+
|
9
|
+
def params
|
10
|
+
Hash.new { |h, k| k }
|
11
|
+
end
|
12
|
+
public :params
|
13
|
+
|
14
|
+
markup = form :action => '/login' do
|
15
|
+
textfield :name, :label => 'Username', :description => 'Enter your username.'
|
16
|
+
textfield :pass, :label => 'Password', :description => 'Enter your password.'
|
17
|
+
submit 'Login'
|
18
|
+
end
|
19
|
+
|
20
|
+
puts markup
|
data/lib/dm-forms.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#--
|
2
|
-
# Copyright (c) 2008 TJ Holowaychuk
|
2
|
+
# Copyright (c) 2008-2009 TJ Holowaychuk <tj@vision-media.ca>
|
3
3
|
#
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining
|
5
5
|
# a copy of this software and associated documentation files (the
|
@@ -21,12 +21,11 @@
|
|
21
21
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
22
|
#++
|
23
23
|
|
24
|
-
$:.unshift File.dirname(__FILE__)
|
25
|
-
|
26
|
-
require 'rubygems'
|
27
24
|
require 'extlib'
|
25
|
+
require 'rext/all'
|
28
26
|
require 'dm-forms/version'
|
29
27
|
require 'dm-forms/core_ext'
|
30
28
|
require 'dm-forms/tag'
|
31
|
-
require 'dm-forms/
|
32
|
-
require 'dm-forms/
|
29
|
+
require 'dm-forms/helpers'
|
30
|
+
require 'dm-forms/mixins'
|
31
|
+
require 'dm-forms/base'
|
@@ -0,0 +1,115 @@
|
|
1
|
+
|
2
|
+
module DataMapper
|
3
|
+
module Form
|
4
|
+
class Base
|
5
|
+
|
6
|
+
include Tag
|
7
|
+
|
8
|
+
REGULAR_ELEMENTS = :textarea, :select
|
9
|
+
SELF_CLOSING_ELEMENTS = :textfield, :submit, :file, :button, :hidden, :password, :radio, :checkbox
|
10
|
+
DEFAULT_VALUE_ELEMENTS = :textarea, :select, :textfield, :radio, :checkbox
|
11
|
+
|
12
|
+
attr_reader :model, :origin, :name
|
13
|
+
|
14
|
+
def initialize model = nil, origin = nil
|
15
|
+
@model, @origin = model, origin
|
16
|
+
@name = model.class.name.downcase.split('::').last
|
17
|
+
end
|
18
|
+
|
19
|
+
def form attrs = {}, &block
|
20
|
+
origin.clear_buffer
|
21
|
+
captured = origin.capture &block
|
22
|
+
faux_method = process_form_attrs attrs
|
23
|
+
tag :form, faux_method + captured, attrs
|
24
|
+
end
|
25
|
+
|
26
|
+
def fieldset attrs = {}, &block
|
27
|
+
legend_tag = (legend = attrs.delete(:legend)) ? tag(:legend, legend) : ''
|
28
|
+
origin.buffer << tag(:fieldset, legend_tag + origin.capture(&block), attrs)
|
29
|
+
end
|
30
|
+
|
31
|
+
def select_options options, selected = nil, prompt = nil
|
32
|
+
options[''] = prompt unless prompt.nil?
|
33
|
+
selected ||= prompt || nil
|
34
|
+
options.map do |value, contents|
|
35
|
+
tag :option, contents, :value => value, :selected => (value == selected or contents == selected)
|
36
|
+
end.join("\n")
|
37
|
+
end
|
38
|
+
|
39
|
+
def unbound_textarea *args
|
40
|
+
contents, attrs = split_args *args
|
41
|
+
process_unbound_element :textarea, attrs
|
42
|
+
origin.buffer << tag(:textarea, element_value(attrs) || contents, attrs)
|
43
|
+
end
|
44
|
+
|
45
|
+
def unbound_select attrs = {}
|
46
|
+
options = select_options *attrs.extract!(:options, :selected, :prompt)
|
47
|
+
process_unbound_element :select, attrs
|
48
|
+
origin.buffer << tag(:select, options, attrs)
|
49
|
+
end
|
50
|
+
|
51
|
+
SELF_CLOSING_ELEMENTS.each do |type|
|
52
|
+
define_method :"unbound_#{type}" do |attrs|
|
53
|
+
process_unbound_element type, attrs
|
54
|
+
origin.buffer << self_closing_tag(:input, attrs)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
(SELF_CLOSING_ELEMENTS | REGULAR_ELEMENTS).each do |type|
|
59
|
+
define_method :"bound_#{type}" do |*args|
|
60
|
+
method, attrs = args.shift, args.shift || {}
|
61
|
+
process_bound_element type, method, attrs
|
62
|
+
send :"unbound_#{type}", attrs
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def split_args *args
|
69
|
+
return nil, args.shift if args.first.is_a? Hash
|
70
|
+
return *args
|
71
|
+
end
|
72
|
+
|
73
|
+
def process_bound_element type, method, attrs
|
74
|
+
attrs[:name] = element_name method
|
75
|
+
end
|
76
|
+
|
77
|
+
def process_unbound_element type, attrs
|
78
|
+
attrs ||= {}
|
79
|
+
attrs[:type] = type if type.in? SELF_CLOSING_ELEMENTS
|
80
|
+
attrs[:value] = element_value attrs if type.in?(DEFAULT_VALUE_ELEMENTS - REGULAR_ELEMENTS)
|
81
|
+
case type
|
82
|
+
when :file
|
83
|
+
@multipart = true
|
84
|
+
when :submit
|
85
|
+
attrs[:name] ||= 'submit'
|
86
|
+
attrs[:value] ||= 'Submit'
|
87
|
+
end
|
88
|
+
raise ArgumentError, 'form elements must have a name', caller unless attrs.include? :name
|
89
|
+
end
|
90
|
+
|
91
|
+
def process_form_attrs attrs = {}
|
92
|
+
attrs[:method] ||= :post
|
93
|
+
method = attrs[:method]
|
94
|
+
attrs[:method] = :post if attrs[:method] != :get
|
95
|
+
attrs[:enctype] = 'multipart/form-data' if @multipart || attrs.delete(:multipart)
|
96
|
+
method.in?(:post, :get) ? '' : faux_method(method)
|
97
|
+
end
|
98
|
+
|
99
|
+
def faux_method method
|
100
|
+
unbound_hidden :name => '_method', :value => method
|
101
|
+
end
|
102
|
+
|
103
|
+
def element_name method
|
104
|
+
model ? "#{name}[#{method}]" : method
|
105
|
+
end
|
106
|
+
|
107
|
+
def element_value attrs = {}
|
108
|
+
# TODO: escape HTML
|
109
|
+
# TODO: dont use this name hack... better positioning to assign element_name to prevent this
|
110
|
+
model ? model.send(attrs[:name].gsub(/\w+\[|\]/, '')) : origin.params[attrs[:name]]
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|