public
Description: A Ruby web application framework
Homepage: http://www.mackframework.com
Clone URL: git://github.com/markbates/mack.git
Click here to lend your support to: mack and make a donation at www.pledgie.com !
More work on adding html form helpers. [#19]
markbates (author)
Thu Aug 14 11:24:01 -0700 2008
commit  25aed1978f46fb7a93ba6695563aa9ae4103c20d
tree    9a1b167645538c9ddab92de092649c35a0518e77
parent  484cb93a90cc2900b73737e03f0d85e362610f86
...
1
2
3
4
5
 
6
7
8
9
 
10
11
12
13
 
14
15
16
17
 
18
19
20
21
 
22
23
24
25
 
26
27
28
29
 
30
31
32
33
 
34
35
36
37
 
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
 
67
68
69
70
...
1
2
3
 
 
4
5
6
7
 
8
9
10
11
 
12
13
14
15
 
16
17
18
19
 
20
21
22
23
 
24
25
26
27
 
28
29
30
31
 
32
33
34
35
 
36
37
38
39
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
41
42
43
44
0
@@ -1,69 +1,43 @@
0
 class Symbol
0
   
0
   def check_box(*args)
0
-    puts caller.inspect
0
-    fe = FormElement.new(*args)
0
+    Thread.current[:view_template].check_box(self, *args)
0
   end
0
   
0
   def file_field(*args)
0
-    
0
+    Thread.current[:view_template].file_field(self, *args)
0
   end
0
   
0
   def hidden_field(*args)
0
-    
0
+    Thread.current[:view_template].hidden_field(self, *args)
0
   end
0
   
0
   def image_submit(*args)
0
-    
0
+    Thread.current[:view_template].image_submit(self, *args)
0
   end
0
   
0
   def label(*args)
0
-    
0
+    Thread.current[:view_template].label(self, *args)
0
   end
0
   
0
   def radio_button(*args)
0
-    
0
+    Thread.current[:view_template].radio_button(self, *args)
0
   end
0
   
0
   def select(*args)
0
-    
0
+    Thread.current[:view_template].select(self, *args)
0
   end
0
   
0
   def submit(*args)
0
-    
0
+    Thread.current[:view_template].submit(self, *args)
0
   end
0
   
0
   def text_area(*args)
0
-    
0
+    Thread.current[:view_template].text_area(self, *args)
0
   end
0
   
0
   def text_field(*args)
0
-    
0
-  end
0
-  
0
-  private
0
-  class FormElement
0
-    attr_accessor :calling_method
0
-    attr_accessor :options
0
-    
0
-    def initialize(*args)
0
-      args = args.parse_splat_args
0
-      case args
0
-      when Symbol, String
0
-        self.calling_method = args
0
-      when Hash
0
-        self.options = args
0
-      when Array
0
-        self.calling_method = args[0]
0
-        self.options = args[1]
0
-      when nil
0
-        self.calling_method = :to_s
0
-        self.options = {}
0
-      else
0
-        raise ArgumentError.new("You must provide either a Symbol, a String, a Hash, or a combination thereof.")
0
-      end
0
-    end
0
-    
0
+    Thread.current[:view_template].text_field(self, *args)
0
   end
0
   
0
 end
0
\ No newline at end of file
...
25
26
27
28
29
30
31
32
 
 
 
 
33
...
25
26
27
 
 
 
 
28
29
30
31
32
33
0
@@ -25,7 +25,7 @@ Mack::ControllerHelpers.constants.each do |cont|
0
 end
0
 
0
 # Find view level Helpers and include them into the Mack::Rendering::ViewTemplate
0
-Mack::ViewHelpers.constants.each do |cont|
0
-  h = "Mack::ViewHelpers::#{cont}".constantize
0
-  h.include_safely_into(Mack::Rendering::ViewTemplate)
0
-end
0
\ No newline at end of file
0
+# Mack::ViewHelpers.constants.each do |cont|
0
+#   h = "Mack::ViewHelpers::#{cont}".constantize
0
+#   h.include_safely_into(Mack::Rendering::ViewTemplate)
0
+# end
0
\ No newline at end of file
...
3
4
5
 
6
7
8
...
14
15
16
 
17
18
19
...
3
4
5
6
7
8
9
...
15
16
17
18
19
20
21
0
@@ -3,6 +3,7 @@ module Mack
0
     # This class is used to do all the view level bindings.
0
     # It allows for seperation between the Mack::Controller and the view levels.
0
     class ViewTemplate
0
+      include Mack::ViewHelpers
0
       
0
       # Allows access to any options passed into the template.
0
       attr_accessor :options
0
@@ -14,6 +15,7 @@ module Mack
0
         self.render_value = render_value
0
         self.options = options
0
         @_yield_to_cache = {}
0
+        Thread.current[:view_template] = self
0
       end
0
       
0
       # Allows access to the current Mack::Controller object.
...
23
24
25
 
 
 
 
 
26
27
 
28
29
30
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
32
33
...
23
24
25
26
27
28
29
30
31
 
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
0
@@ -23,11 +23,136 @@ module Mack
0
         # content_tag(:form, options, &block)
0
       end
0
       
0
+      def submit_tag(value = "Submit", options = {}, *original_args)
0
+        Mack.logger.warn("DEPRECATED: 'submit_tag'. Please use 'submit' instead")
0
+        submit(value, options, *original_args)
0
+      end
0
+      
0
       # Builds an HTML submit tag
0
-      def submit_tag(value = "Submit", options = {})
0
+      def submit(value = "Submit", options = {}, *original_args)
0
         non_content_tag(:input, {:type => :submit, :value => value}.merge(options))
0
       end
0
       
0
+      def check_box(name, *args)
0
+        build_form_element(name, {:type => :checkbox}, *args) do |var, fe, options|
0
+          if options[:value]
0
+            options.merge!(:checked => "checked")
0
+          end
0
+          options.delete(:value)
0
+        end
0
+      end
0
+
0
+      def file_field(name, *args)
0
+        build_form_element(name, {:type => :file}, *args)
0
+      end
0
+
0
+      def hidden_field(name, *args)
0
+        build_form_element(name, {:type => :hidden}, *args)
0
+      end
0
+
0
+      def image_submit(src, options = {})
0
+        non_content_tag(:input, {:type => :image, :src => "/images/#{src}"}.merge(options))
0
+      end
0
+
0
+      def label(name, *args)
0
+        fe = FormElement.new(*args)
0
+        unless fe.options[:for]
0
+          fe.options[:for] = (fe.calling_method == :to_s ? name.to_s : "#{name}_#{fe.calling_method}")
0
+        end
0
+        unless fe.options[:value]
0
+          fe.options[:value] = (fe.calling_method == :to_s ? name.to_s.humanize : fe.calling_method.to_s.humanize)
0
+        end
0
+        content = fe.options[:value]
0
+        fe.options.delete(:value)
0
+        content_tag(:label, fe.options, content)
0
+      end
0
+
0
+      def radio_button(name, *args)
0
+        build_form_element(name, {:type => :radio}, *args) do |var, fe, options|
0
+          if options[:value]
0
+            options.merge!(:checked => "checked")
0
+          end
0
+          options.delete(:value)
0
+        end
0
+      end
0
+
0
+      def select(name, *args)
0
+
0
+      end
0
+
0
+      def text_area(name, *args)
0
+        var = instance_variable_get("@#{name}")
0
+        fe = FormElement.new(*args)
0
+        options = {:name => name, :id => name}
0
+        if var.nil?
0
+          return content_tag(:textarea, options.merge(fe.options))
0
+        else
0
+          unless fe.calling_method == :to_s
0
+            options.merge!(:name => "#{name}[#{fe.calling_method}]", :id => "#{name}_#{fe.calling_method}")
0
+          end
0
+          options[:value] = var.send(fe.calling_method)
0
+          
0
+          yield var, fe, options if block_given?
0
+          
0
+          content = options[:value]
0
+          options.delete(:value)
0
+          
0
+          return content_tag(:textarea, options.merge(fe.options), content)
0
+        end
0
+      end
0
+
0
+      def text_field(name, *args)
0
+        build_form_element(name, {:type => :text}, *args)
0
+      end
0
+      
0
+      def password_field(name, *args)
0
+        build_form_element(name, {:type => :password}, *args)
0
+      end
0
+      
0
+      private
0
+      def build_form_element(name, options, *original_args)
0
+        var = instance_variable_get("@#{name}")
0
+        options = {:name => name, :id => name}.merge(options)
0
+        if var.nil?
0
+          return non_content_tag(:input, options)
0
+        else
0
+          fe = FormElement.new(*original_args)
0
+          unless fe.calling_method == :to_s
0
+            options.merge!(:name => "#{name}[#{fe.calling_method}]", :id => "#{name}_#{fe.calling_method}")
0
+          end
0
+          options[:value] = var.send(fe.calling_method)
0
+          
0
+          yield var, fe, options if block_given?
0
+          
0
+          return non_content_tag(:input, options.merge(fe.options))
0
+        end
0
+      end
0
+      
0
+      class FormElement
0
+
0
+        attr_accessor :calling_method
0
+        attr_accessor :options
0
+
0
+        def initialize(*args)
0
+          args = args.parse_splat_args
0
+          self.calling_method = :to_s
0
+          self.options = {}
0
+          case args
0
+          when Symbol, String
0
+            self.calling_method = args
0
+          when Hash
0
+            self.options = args
0
+          when Array
0
+            self.calling_method = args[0]
0
+            self.options = args[1]
0
+          when nil
0
+          else
0
+            raise ArgumentError.new("You must provide either a Symbol, a String, a Hash, or a combination thereof.")
0
+          end
0
+        end
0
+
0
+      end
0
+      
0
       
0
     end # FormHelpers
0
   end # ViewHelpers
...
39
40
41
 
 
 
42
43
44
...
39
40
41
42
43
44
45
46
47
0
@@ -39,6 +39,9 @@ module Mack
0
       
0
       private
0
       def build_options(options)
0
+        if options[:disabled]
0
+          options[:disabled] = :disabled
0
+        end
0
         opts = ""
0
         unless options.empty?
0
           opts = " " << options.join("%s=\"%s\"", " ")
...
4
5
6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
8
9
...
43
44
45
46
 
47
48
49
 
50
51
52
53
 
54
55
56
57
 
58
59
60
...
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
...
259
260
261
 
262
263
264
 
265
266
267
268
 
269
270
271
272
 
273
274
275
276
0
@@ -4,6 +4,222 @@ require Pathname(__FILE__).dirname.expand_path.parent.parent + 'spec_helper'
0
 describe Mack::ViewHelpers::FormHelpers do
0
   include Mack::ViewHelpers
0
   
0
+  class Cop
0
+    attr_accessor :full_name
0
+    attr_accessor :level
0
+    attr_accessor :tos
0
+    attr_accessor :bio_file
0
+  end
0
+
0
+  before(:each) do
0
+    @cop = Cop.new
0
+    @cop.full_name = "ness"
0
+    @cop.level = 1
0
+    @cop.bio_file = "~/bio.doc"
0
+    @simple = "hi"
0
+    @default_file = "~/resume.doc"
0
+  end
0
+  
0
+  describe "check_box" do
0
+    
0
+    it "should create a nested checkbox for a model" do
0
+      check_box(:cop, :tos).should == %{<input id="cop_tos" name="cop[tos]" type="checkbox" />}
0
+    end
0
+    
0
+    it "should create a non-nested checkbox for a simple object" do
0
+      check_box(:simple).should == %{<input checked="checked" id="simple" name="simple" type="checkbox" />}
0
+    end
0
+    
0
+    it "should create a non-nested checkbox for just a symbol" do
0
+      check_box(:unknown).should == %{<input id="unknown" name="unknown" type="checkbox" />}
0
+    end
0
+    
0
+    it "should be checked if the value is true" do
0
+      @cop.tos = true
0
+      check_box(:cop, :tos).should == %{<input checked="checked" id="cop_tos" name="cop[tos]" type="checkbox" />}
0
+    end
0
+    
0
+    it "should be unchecked if the value is false" do
0
+      @cop.tos = false
0
+      check_box(:cop, :tos).should == %{<input id="cop_tos" name="cop[tos]" type="checkbox" />}
0
+    end
0
+    
0
+  end
0
+  
0
+  describe "file_field" do
0
+    
0
+    it "should create a nested file_field for a model" do
0
+      file_field(:cop, :bio_file).should == %{<input id="cop_bio_file" name="cop[bio_file]" type="file" value="~/bio.doc" />}
0
+    end
0
+    
0
+    it "should create a non-nested file_field for a simple object" do
0
+      file_field(:default_file).should == %{<input id="default_file" name="default_file" type="file" value="~/resume.doc" />}
0
+    end
0
+    
0
+    it "should create a non-nested file_field for just a symbol" do
0
+      file_field(:unknown).should == %{<input id="unknown" name="unknown" type="file" />}
0
+    end
0
+
0
+    it "should create a nested file_field for a model with an empty value if value is false" do
0
+      @cop.bio_file = nil
0
+      file_field(:cop, :bio_file).should == %{<input id="cop_bio_file" name="cop[bio_file]" type="file" value="" />}
0
+    end
0
+    
0
+  end
0
+  
0
+  describe "hidden_field" do
0
+    
0
+    it "should create a nested hidden_field for a model" do
0
+      hidden_field(:cop, :full_name).should == %{<input id="cop_full_name" name="cop[full_name]" type="hidden" value="ness" />}
0
+    end
0
+    
0
+    it "should create a non-nested hidden_field for a simple object" do
0
+      hidden_field(:simple).should == %{<input id="simple" name="simple" type="hidden" value="hi" />}
0
+    end
0
+    
0
+    it "should create a non-nested hidden_field for just a symbol" do
0
+      hidden_field(:unknown).should == %{<input id="unknown" name="unknown" type="hidden" />}
0
+    end
0
+
0
+    it "should create a nested hidden_field for a model with an empty value if value is false" do
0
+      @cop.full_name = nil
0
+      hidden_field(:cop, :full_name).should == %{<input id="cop_full_name" name="cop[full_name]" type="hidden" value="" />}
0
+    end
0
+    
0
+  end
0
+  
0
+  describe "password_field" do
0
+    
0
+    it "should create a nested password_field for a model" do
0
+      password_field(:cop, :full_name).should == %{<input id="cop_full_name" name="cop[full_name]" type="password" value="ness" />}
0
+    end
0
+    
0
+    it "should create a non-nested password_field for a simple object" do
0
+      password_field(:simple).should == %{<input id="simple" name="simple" type="password" value="hi" />}
0
+    end
0
+    
0
+    it "should create a non-nested password_field for just a symbol" do
0
+      password_field(:unknown).should == %{<input id="unknown" name="unknown" type="password" />}
0
+    end
0
+
0
+    it "should create a nested password_field for a model with an empty value if value is false" do
0
+      @cop.full_name = nil
0
+      password_field(:cop, :full_name).should == %{<input id="cop_full_name" name="cop[full_name]" type="password" value="" />}
0
+    end
0
+    
0
+  end
0
+  
0
+  describe "image_submit" do
0
+    
0
+    it "should create an image submit tag" do
0
+      image_submit("login.png").should == %{<input src="/images/login.png" type="image" />}
0
+      image_submit("purchase.png", :disabled => true).should == %{<input disabled="disabled" src="/images/purchase.png" type="image" />}
0
+      image_submit("search.png", :class => 'search-button').should == %{<input class="search-button" src="/images/search.png" type="image" />}
0
+    end
0
+    
0
+  end
0
+  
0
+  describe "label" do
0
+    
0
+    it "should create a nested label for a model" do
0
+      label(:cop, :full_name).should == %{<label for="cop_full_name">Full name</label>}
0
+    end
0
+    
0
+    it "should create a non-nested label for a simple object" do
0
+      label(:simple).should == %{<label for="simple">Simple</label>}
0
+    end
0
+    
0
+    it "should create a non-nested label for just a symbol" do
0
+      label(:unknown).should == %{<label for="unknown">Unknown</label>}
0
+    end
0
+    
0
+    it "should create a non-nested label for just a symbol" do
0
+      label(:unknown).should == %{<label for="unknown">Unknown</label>}
0
+    end
0
+    
0
+    it "should create a non-nested label and use :value for it's content" do
0
+      label(:unknown, :value => "My Label").should == %{<label for="unknown">My Label</label>}
0
+    end
0
+    
0
+    it "should create a non-nested label and use :for for it's for" do
0
+      label(:unknown, :for => "my_label").should == %{<label for="my_label">Unknown</label>}
0
+    end
0
+    
0
+  end
0
+  
0
+  describe "radio_button" do
0
+    
0
+    it "should create a nested radio_button for a model" do
0
+      radio_button(:cop, :tos).should == %{<input id="cop_tos" name="cop[tos]" type="radio" />}
0
+    end
0
+    
0
+    it "should create a non-nested radio_button for a simple object" do
0
+      radio_button(:simple).should == %{<input checked="checked" id="simple" name="simple" type="radio" />}
0
+    end
0
+    
0
+    it "should create a non-nested radio_button for just a symbol" do
0
+      radio_button(:unknown).should == %{<input id="unknown" name="unknown" type="radio" />}
0
+    end
0
+    
0
+    it "should be checked if the value is true" do
0
+      @cop.tos = true
0
+      radio_button(:cop, :tos).should == %{<input checked="checked" id="cop_tos" name="cop[tos]" type="radio" />}
0
+    end
0
+    
0
+    it "should be unchecked if the value is false" do
0
+      @cop.tos = false
0
+      radio_button(:cop, :tos).should == %{<input id="cop_tos" name="cop[tos]" type="radio" />}
0
+    end
0
+    
0
+  end
0
+  
0
+  describe "select" do
0
+    
0
+  end
0
+  
0
+  describe "text_area" do
0
+    
0
+    it "should create a nested text_area for a model" do
0
+      text_area(:cop, :full_name).should == %{<textarea id="cop_full_name" name="cop[full_name]">ness</textarea>}
0
+    end
0
+    
0
+    it "should create a non-nested text_area for a simple object" do
0
+      text_area(:simple).should == %{<textarea id="simple" name="simple">hi</textarea>}
0
+    end
0
+    
0
+    it "should create a non-nested text_area for just a symbol" do
0
+      text_area(:unknown).should == %{<textarea id="unknown" name="unknown"></textarea>}
0
+    end
0
+
0
+    it "should create a nested text_area for a model with an empty value if value is false" do
0
+      @cop.full_name = nil
0
+      text_area(:cop, :full_name).should == %{<textarea id="cop_full_name" name="cop[full_name]"></textarea>}
0
+    end
0
+    
0
+  end
0
+  
0
+  describe "text_field" do
0
+    
0
+    it "should create a nested text_field for a model" do
0
+      text_field(:cop, :full_name).should == %{<input id="cop_full_name" name="cop[full_name]" type="text" value="ness" />}
0
+    end
0
+    
0
+    it "should create a non-nested text_field for a simple object" do
0
+      text_field(:simple).should == %{<input id="simple" name="simple" type="text" value="hi" />}
0
+    end
0
+    
0
+    it "should create a non-nested text_field for just a symbol" do
0
+      text_field(:unknown).should == %{<input id="unknown" name="unknown" type="text" />}
0
+    end
0
+
0
+    it "should create a nested text_field for a model with an empty value if value is false" do
0
+      @cop.full_name = nil
0
+      text_field(:cop, :full_name).should == %{<input id="cop_full_name" name="cop[full_name]" type="text" value="" />}
0
+    end
0
+    
0
+  end
0
+  
0
+  
0
   describe "form" do
0
     include CommonHelpers
0
     
0
@@ -43,18 +259,18 @@ Hello
0
     
0
   end
0
   
0
-  describe "submit_tag" do
0
+  describe "submit" do
0
     
0
     it "should build a simple submit tag" do
0
-      submit_tag.should == %{<input type="submit" value="Submit" />}
0
+      submit.should == %{<input type="submit" value="Submit" />}
0
     end
0
     
0
     it "should allow you to change the value" do
0
-      submit_tag("Login").should == %{<input type="submit" value="Login" />}
0
+      submit("Login").should == %{<input type="submit" value="Login" />}
0
     end
0
     
0
     it "should take options" do
0
-      submit_tag("Login", {:class => :foo}).should == %{<input class="foo" type="submit" value="Login" />}
0
+      submit("Login", {:class => :foo}).should == %{<input class="foo" type="submit" value="Login" />}
0
     end
0
     
0
   end

Comments