formidable 0.0.1
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/.gitignore +10 -0
- data/CHANGELOG +2 -0
- data/Gemfile +7 -0
- data/LICENSE +20 -0
- data/README.textile +78 -0
- data/TODO.txt +3 -0
- data/deps.rip +5 -0
- data/examples/basic.rb +41 -0
- data/examples/post.rb +65 -0
- data/examples/posts/config.ru +48 -0
- data/examples/posts/form.html.haml +19 -0
- data/examples/posts/models.rb +7 -0
- data/formidable.gemspec +38 -0
- data/formidable.pre.gemspec +8 -0
- data/lib/formidable.rb +9 -0
- data/lib/formidable/coercions.rb +50 -0
- data/lib/formidable/elements.rb +196 -0
- data/lib/formidable/renderers/nokogiri.rb +53 -0
- data/lib/formidable/renderers/string.rb +115 -0
- data/lib/formidable/rendering.rb +42 -0
- data/lib/formidable/validations.rb +94 -0
- data/lib/formidable/validations/class.rb +24 -0
- data/lib/formidable/validations/confirmation.rb +58 -0
- data/lib/formidable/validations/equality.rb +25 -0
- data/lib/formidable/validations/format.rb +23 -0
- data/lib/formidable/validations/length.rb +39 -0
- data/lib/formidable/validations/presence.rb +17 -0
- data/lib/formidable/version.rb +5 -0
- data/spec/formidable/coercions_spec.rb +106 -0
- data/spec/formidable/elements_spec.rb +21 -0
- data/spec/formidable/renderers/nokogiri_spec.rb +9 -0
- data/spec/formidable/renderers/string_spec.rb +9 -0
- data/spec/formidable/rendering_spec.rb +0 -0
- data/spec/formidable/validations/class_spec.rb +0 -0
- data/spec/formidable/validations/confirmation_spec.rb +0 -0
- data/spec/formidable/validations/equality_spec.rb +0 -0
- data/spec/formidable/validations/format_spec.rb +0 -0
- data/spec/formidable/validations/length_spec.rb +0 -0
- data/spec/formidable/validations/presence_spec.rb +0 -0
- data/spec/formidable/validations_spec.rb +9 -0
- data/spec/formidable_spec.rb +51 -0
- data/spec/spec.opts +6 -0
- data/spec/spec_helper.rb +13 -0
- data/tasks.rb +38 -0
- data/vendor/cache/validatable-1.6.7.gem +0 -0
- metadata +107 -0
data/.gitignore
ADDED
data/CHANGELOG
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Jakub Stastny aka Botanicus & Pavel Kunc
|
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/README.textile
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
h1. About
|
2
|
+
|
3
|
+
Formidable takes care about your forms. You write a class and
|
4
|
+
|
5
|
+
* Get logic out of your views.
|
6
|
+
* Get logic out of your controllers (presenter pattern).
|
7
|
+
* Validations will work even if the form can't be mapped directly to the models.
|
8
|
+
* You can unit test your forms directly without touching the template layer at all.
|
9
|
+
|
10
|
+
* Validations
|
11
|
+
* Coercions
|
12
|
+
|
13
|
+
Forms contains quite complex logic which definitely shouldn't be in your views
|
14
|
+
|
15
|
+
h2. Defining Forms
|
16
|
+
|
17
|
+
h2. Saving Forms
|
18
|
+
|
19
|
+
h2. Validations
|
20
|
+
|
21
|
+
h2. Renderers
|
22
|
+
|
23
|
+
h2. Custom Fields
|
24
|
+
|
25
|
+
h2. Ideas
|
26
|
+
|
27
|
+
JS validation plugin
|
28
|
+
|
29
|
+
h1. Usage
|
30
|
+
|
31
|
+
h2. Form Definitions
|
32
|
+
|
33
|
+
<pre>
|
34
|
+
|
35
|
+
</pre>
|
36
|
+
|
37
|
+
h2. Controller Code
|
38
|
+
|
39
|
+
<pre>
|
40
|
+
class Posts
|
41
|
+
def new
|
42
|
+
@form ||= PostForm.new
|
43
|
+
@form.attributes[:method] = "POST"
|
44
|
+
end
|
45
|
+
|
46
|
+
def edit
|
47
|
+
@form ||= PostForm.new
|
48
|
+
@form.attributes[:method] = "PUT"
|
49
|
+
end
|
50
|
+
|
51
|
+
def create(raw_data)
|
52
|
+
@form = PostForm.new(nil, raw_data)
|
53
|
+
if @form.save
|
54
|
+
redirect url(:posts)
|
55
|
+
else
|
56
|
+
self.new
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def update(id, raw_data)
|
61
|
+
@form = PostForm.new(nil, raw_data)
|
62
|
+
if @form.update(id)
|
63
|
+
redirect url(:posts)
|
64
|
+
else
|
65
|
+
self.edit
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
</pre>
|
70
|
+
|
71
|
+
You can find more examples at the @examples@ directory.
|
72
|
+
|
73
|
+
h1. Links
|
74
|
+
|
75
|
+
* "Source Code":http://github.com/botanicus/formidable
|
76
|
+
* "Wiki":http://wiki.github.com/botanicus/formidable
|
77
|
+
* "API Docs":http://rdoc.info/projects/botanicus/formidable
|
78
|
+
* "Bug reporting":http://github.com/botanicus/formidable/issues
|
data/TODO.txt
ADDED
data/deps.rip
ADDED
data/examples/basic.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
|
4
|
+
|
5
|
+
require "formidable"
|
6
|
+
require "formidable/validations/presence"
|
7
|
+
|
8
|
+
class BasicForm < Formidable::Elements::Form
|
9
|
+
def setup(&block)
|
10
|
+
text_field(:name, id: "basic_form-name")
|
11
|
+
.validate_presence
|
12
|
+
.coerce { |value| value.to_i }
|
13
|
+
|
14
|
+
text_field(:rating, id: "basic_form-rating")
|
15
|
+
.validate_presence
|
16
|
+
.coerce(Integer)
|
17
|
+
|
18
|
+
fieldset(:i_brake_it) do
|
19
|
+
legend("yyyy", id: 'xxx')
|
20
|
+
text_field(:nono, id: "nono").validate_presence
|
21
|
+
end
|
22
|
+
|
23
|
+
group(:i_m_group) do
|
24
|
+
text_field(:groupa, id: 'xy')
|
25
|
+
end
|
26
|
+
block.call if block
|
27
|
+
submit("Save")
|
28
|
+
end
|
29
|
+
|
30
|
+
def save
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class MyForm < BasicForm
|
36
|
+
def setup
|
37
|
+
super do
|
38
|
+
text_field(:super_duper, id: 'super_duper')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/examples/post.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# text_field, text_area -> value = raw_data[key]
|
4
|
+
# raw_data == user: {}, tags: [{name: "Ruby"}]
|
5
|
+
# form = PostForm.new(@post.values, Author.all)
|
6
|
+
class PostForm < Formidable::Form
|
7
|
+
namespace :post
|
8
|
+
def initialize(raw_data, authors)
|
9
|
+
super(raw_data)
|
10
|
+
@authors = authors
|
11
|
+
end
|
12
|
+
|
13
|
+
text_field(:title)
|
14
|
+
.validate_presence.
|
15
|
+
text_field(:title) do
|
16
|
+
validate_presence
|
17
|
+
end
|
18
|
+
|
19
|
+
check_box(:published)
|
20
|
+
text_area
|
21
|
+
|
22
|
+
group(:tydenni_menu) do
|
23
|
+
check_box :svickova
|
24
|
+
check_box :knedlo_zelo
|
25
|
+
validate do
|
26
|
+
self.fields.inject(0) do |sum, check_box|
|
27
|
+
sum += 1 if check_box.selected?
|
28
|
+
sum
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
select(:author) do
|
34
|
+
@authors.each do |author|
|
35
|
+
option selected: (author == raw_data[:author])
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
submit(value: "Save")
|
40
|
+
button(type: "submit") { "Save" }
|
41
|
+
|
42
|
+
field(:password, id: "sdf") do
|
43
|
+
validate_length (0..10)
|
44
|
+
validate do
|
45
|
+
form.password_confirmation == value
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
field(:password_confirmation) do
|
50
|
+
validate { form.password == value }
|
51
|
+
end
|
52
|
+
|
53
|
+
fields_for(:author) do
|
54
|
+
field()
|
55
|
+
end
|
56
|
+
|
57
|
+
# <fieldset>
|
58
|
+
# <legend>User</legend>
|
59
|
+
# </fieldset>
|
60
|
+
fieldset("User") do
|
61
|
+
field(:name)
|
62
|
+
end
|
63
|
+
|
64
|
+
field(:tags, id: -> { |tag| "tag-#{tag.id}"}, array: true)
|
65
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
class Posts
|
4
|
+
def self.dispatcher(action)
|
5
|
+
Proc.new do |env|
|
6
|
+
self.new(env).send(action)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(env)
|
11
|
+
@env = env
|
12
|
+
end
|
13
|
+
|
14
|
+
def index
|
15
|
+
end
|
16
|
+
|
17
|
+
def new
|
18
|
+
@form ||= PostForm.new
|
19
|
+
@form.attributes[:method] = "POST"
|
20
|
+
end
|
21
|
+
|
22
|
+
def edit
|
23
|
+
@form ||= PostForm.new
|
24
|
+
@form.attributes[:method] = "PUT"
|
25
|
+
end
|
26
|
+
|
27
|
+
def create(raw_data)
|
28
|
+
@form = PostForm.new(nil, raw_data)
|
29
|
+
if @form.save
|
30
|
+
redirect url(:posts)
|
31
|
+
else
|
32
|
+
self.new
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def update(id, raw_data)
|
37
|
+
@form = PostForm.new(nil, raw_data)
|
38
|
+
if @form.update(id)
|
39
|
+
redirect url(:posts)
|
40
|
+
else
|
41
|
+
self.edit
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
map("/posts") do
|
47
|
+
Posts.dispatcher(:index)
|
48
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
/ You might not need to have a template for your form. In case you
|
2
|
+
/ don't have any special need, just use form.render and that's it.
|
3
|
+
|
4
|
+
/ Specify renderer you want to use.
|
5
|
+
= form.errors.render(ErrorsListRenderer.new)
|
6
|
+
|
7
|
+
/ Haml tags can take hash as an argument, so why not simply use form.attributes.
|
8
|
+
%form{form.attributes}
|
9
|
+
/ Render tags you want to display.
|
10
|
+
= form.post.title.render
|
11
|
+
/ Iterate over elements
|
12
|
+
- form.post.tags.each do |tag|
|
13
|
+
= tag.render
|
14
|
+
/ Or write fully customized HTML.
|
15
|
+
%label{for: "input-body"}
|
16
|
+
- if form.post.errors.on(:title)
|
17
|
+
%input#input-title.errors{name: "post[title]", value: form.post.title}
|
18
|
+
- else
|
19
|
+
%input#input-title{name: "post[title]", value: form.post.title}
|
data/formidable.gemspec
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/usr/bin/env gem build
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
# Run ./form.gemspec or gem build form.gemspec
|
5
|
+
# NOTE: we can't use require_relative because when we run gem build, it use eval for executing this file
|
6
|
+
require File.expand_path("../lib/formidable/version", __FILE__)
|
7
|
+
require "base64"
|
8
|
+
|
9
|
+
Gem::Specification.new do |s|
|
10
|
+
s.name = "formidable"
|
11
|
+
s.version = Formidable::VERSION
|
12
|
+
s.authors = ["Jakub Stastny aka Botanicus", "Pavel Kunc"]
|
13
|
+
s.homepage = "http://github.com/botanicus/formidable"
|
14
|
+
s.summary = "" # TODO: summary
|
15
|
+
s.description = "" # TODO: long description
|
16
|
+
s.cert_chain = nil
|
17
|
+
s.email = Base64.decode64("c3Rhc3RueUAxMDFpZGVhcy5jeg==\n")
|
18
|
+
s.has_rdoc = true
|
19
|
+
|
20
|
+
# files
|
21
|
+
s.files = `git ls-files`.split("\n")
|
22
|
+
|
23
|
+
s.require_paths = ["lib"]
|
24
|
+
|
25
|
+
# Ruby version
|
26
|
+
s.required_ruby_version = ::Gem::Requirement.new(">= 1.9")
|
27
|
+
|
28
|
+
begin
|
29
|
+
require "changelog"
|
30
|
+
rescue LoadError
|
31
|
+
warn "You have to have changelog gem installed for post install message"
|
32
|
+
else
|
33
|
+
s.post_install_message = CHANGELOG.new.version_changes
|
34
|
+
end
|
35
|
+
|
36
|
+
# RubyForge
|
37
|
+
s.rubyforge_project = "formidable"
|
38
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
#!/usr/bin/env gem build
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
# You might think this is a terrible mess and guess what, you're
|
5
|
+
# right mate! However say thanks to authors of RubyGems, not me.
|
6
|
+
eval(File.read("form.gemspec")).tap do |specification|
|
7
|
+
specification.version = "#{specification.version}.pre"
|
8
|
+
end
|
data/lib/formidable.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Formidable
|
4
|
+
module Coercions
|
5
|
+
MissingCoercion = Class.new(StandardError)
|
6
|
+
IncompatibleInterface = Class.new(StandardError)
|
7
|
+
|
8
|
+
def self.coercions
|
9
|
+
@coercions ||= Hash.new do |hash, key|
|
10
|
+
raise MissingCoercion, "No coercion defined for #{key}"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# default coercions
|
15
|
+
coercions[:integer] = Proc.new { |value| value.to_i }
|
16
|
+
coercions[:float] = Proc.new { |value| value.to_f }
|
17
|
+
|
18
|
+
def self.included(klass)
|
19
|
+
if ! klass.method_defined?(:raw_data) || ! klass.method_defined?(:cleaned_data=)
|
20
|
+
raise IncompatibleInterface, "You are supposed to define #{klass}#raw_data and #{klass}#cleaned_data= in order to get coercions running!"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def cleaned_data
|
25
|
+
@cleaned_data ||= self.coerce!
|
26
|
+
end
|
27
|
+
|
28
|
+
def coercions
|
29
|
+
@coercions ||= Array.new
|
30
|
+
end
|
31
|
+
|
32
|
+
def coerce(type = nil, &block)
|
33
|
+
if type && block.nil?
|
34
|
+
coercions << Coercions.coercions[type]
|
35
|
+
elsif type.nil? && block
|
36
|
+
coercions << block
|
37
|
+
else
|
38
|
+
raise ArgumentError, "provide block or type"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def coerce!
|
43
|
+
self.cleaned_data = begin
|
44
|
+
coercions.inject(self.raw_data) do |coercion, raw_data|
|
45
|
+
coercion.call(raw_data)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,196 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "formidable/coercions"
|
4
|
+
require "formidable/rendering"
|
5
|
+
require "formidable/validations"
|
6
|
+
require "formidable/renderers/string"
|
7
|
+
|
8
|
+
module Formidable
|
9
|
+
module Elements
|
10
|
+
class Element
|
11
|
+
include Rendering
|
12
|
+
include Validations
|
13
|
+
include Coercions
|
14
|
+
|
15
|
+
attr_accessor :name, :raw_data, :content
|
16
|
+
attr_reader :attributes
|
17
|
+
|
18
|
+
def initialize(name, attributes = Hash.new, raw_data = nil)
|
19
|
+
@name, @attributes, @raw_data = name, attributes, raw_data
|
20
|
+
@attributes.merge!(name: name, value: raw_data)
|
21
|
+
end
|
22
|
+
|
23
|
+
def set_raw_data(raw_data)
|
24
|
+
@raw_data = self.attributes[:value] = raw_data
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class ElementList < Element # pro form, group, fieldset
|
29
|
+
# We had a few beers and we decided that this is pretty cool :)
|
30
|
+
# This will define DSL method for creating email_field
|
31
|
+
# @example Formidable::ElementList.register self, :email_field
|
32
|
+
def self.register(klass, method_name)
|
33
|
+
define_method(method_name) do |name, *args, &block|
|
34
|
+
element = klass.new(name, *args, &block)
|
35
|
+
elements << element
|
36
|
+
warn "Overriding method #{name}" if self.class.method_defined?(name)
|
37
|
+
self.class.send(:define_method, name) do
|
38
|
+
element
|
39
|
+
end
|
40
|
+
element
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
include GroupValidations
|
45
|
+
def initialize(*args, &block)
|
46
|
+
super(*args) # we need to get elements first
|
47
|
+
self.instance_eval(&block) if block
|
48
|
+
end
|
49
|
+
|
50
|
+
def elements
|
51
|
+
@elements ||= Array.new
|
52
|
+
end
|
53
|
+
|
54
|
+
def cleaned_data
|
55
|
+
self.elements.inject(Hash.new) do |result, element|
|
56
|
+
result[element.name] = element.cleaned_data
|
57
|
+
result
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def raw_data
|
62
|
+
self.elements.inject(Hash.new) do |result, element|
|
63
|
+
result[element.name] = element.raw_data
|
64
|
+
result
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
protected
|
69
|
+
def set_raw_data(raw_data)
|
70
|
+
self.elements.each do |element|
|
71
|
+
element.set_raw_data(raw_data[element.name]) if raw_data
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
class Form < ElementList
|
77
|
+
renderer Renderers::Form
|
78
|
+
|
79
|
+
# TODO: prefix should be in the form definition (name or namespace)
|
80
|
+
def initialize(prefix = nil, attributes = Hash.new, raw_data = nil)
|
81
|
+
self.setup
|
82
|
+
super(prefix, attributes, raw_data)
|
83
|
+
set_raw_data(raw_data)
|
84
|
+
end
|
85
|
+
|
86
|
+
def setup
|
87
|
+
raise NotImplementedError, "You are supposed to redefine the setup method in subclasses of Element!"
|
88
|
+
end
|
89
|
+
|
90
|
+
def save(*args)
|
91
|
+
raise NotImplementedError, "You have to redefine this method in subclasses!"
|
92
|
+
end
|
93
|
+
alias_method :save!, :save
|
94
|
+
|
95
|
+
def update(*args)
|
96
|
+
raise NotImplementedError, "You have to redefine this method in subclasses!"
|
97
|
+
end
|
98
|
+
alias_method :update!, :update
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
class TextField < Element
|
103
|
+
ElementList.register(self, :text_field)
|
104
|
+
|
105
|
+
def initialize(name, attributes = Hash.new, raw_data = nil)
|
106
|
+
super(name, attributes.merge!(type: "text"), raw_data)
|
107
|
+
end
|
108
|
+
|
109
|
+
renderer Renderers::LabeledInputRenderer
|
110
|
+
end
|
111
|
+
|
112
|
+
class TextArea < Element
|
113
|
+
ElementList.register(self, :text_area)
|
114
|
+
|
115
|
+
renderer Renderers::LabeledInputRenderer
|
116
|
+
end
|
117
|
+
|
118
|
+
class HiddenField < Element
|
119
|
+
ElementList.register(self, :hidden_field)
|
120
|
+
|
121
|
+
renderer Renderers::LabeledInputRenderer
|
122
|
+
end
|
123
|
+
|
124
|
+
class Submit < Element
|
125
|
+
ElementList.register(self, :submit)
|
126
|
+
|
127
|
+
renderer Renderers::SimpleInputRenderer
|
128
|
+
|
129
|
+
def initialize(value = "Submit", attributes = Hash.new, raw_data = Hash.new)
|
130
|
+
super(:submit, attributes.merge(value: value, type: "submit"), raw_data)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
class Button < Element
|
135
|
+
ElementList.register(self, :button)
|
136
|
+
|
137
|
+
renderer Renderers::Button
|
138
|
+
end
|
139
|
+
|
140
|
+
class Group < ElementList
|
141
|
+
ElementList.register(self, :group)
|
142
|
+
|
143
|
+
renderer Renderers::Group
|
144
|
+
end
|
145
|
+
|
146
|
+
class Fieldset < ElementList
|
147
|
+
ElementList.register(self, :fieldset)
|
148
|
+
|
149
|
+
renderer Renderers::Fieldset
|
150
|
+
end
|
151
|
+
|
152
|
+
class Legend < Element
|
153
|
+
Fieldset.register(self, :legend)
|
154
|
+
|
155
|
+
renderer Renderers::SimpleTagRenderer
|
156
|
+
|
157
|
+
def initialize(content, attributes = Hash.new)
|
158
|
+
self.content = content
|
159
|
+
super(:legend, attributes)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
class FileField < Element
|
164
|
+
ElementList.register(self, :file_field)
|
165
|
+
|
166
|
+
renderer Renderers::LabeledInputRenderer
|
167
|
+
|
168
|
+
def initialize(*args)
|
169
|
+
super(*args)
|
170
|
+
self.form.multipart = true
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
class EmailField < TextField
|
175
|
+
ElementList.register(self, :email_field)
|
176
|
+
end
|
177
|
+
|
178
|
+
# zna to svoje name => vi kde v params to najit
|
179
|
+
# {date: "27-07-2010"} => {date: #<Date:x0>}
|
180
|
+
class DateSelectField < Element
|
181
|
+
# TOHLE BUDE V SUPERCLASS
|
182
|
+
# jak to ma dostat params?
|
183
|
+
def deserialize
|
184
|
+
# [:post, :title]
|
185
|
+
self.name.inject(params) do |hash, key|
|
186
|
+
hash[key]
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
# TOHLE BUDE TADY
|
191
|
+
def deserialize
|
192
|
+
Date.new(super)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|