<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>merb_helpers/lib/merb_helpers/form/builder.rb</filename>
    </added>
    <added>
      <filename>merb_helpers/lib/merb_helpers/form/helpers.rb</filename>
    </added>
    <added>
      <filename>merb_helpers/spec/merb_helpers_form_spec.rb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -1,655 +1,14 @@
-require &quot;#{File.dirname(__FILE__)}/tag_helpers&quot;
-
-module Merb
-  
-  # Merb helpers include several helpers used for simplifying view creation.
-  # The available helpers currently include form tag helpers for both resource based and generic HTML form tag creation
-  module Helpers
-    # Provides a number of methods for creating form tags which may be used either with or without the presence of ORM specific models.
-    # There are two types of form helpers: those that specifically work with model attributes and those that don't.
-    # This helper deals with both model attributes and generic form tags. Model attributes generally end in &quot;_control&quot; such as +text_control+,
-    # and generic tags end with &quot;_field&quot;, such as +text_field+
-    #
-    # The core method of this helper, +form_for+, gives you the ability to create a form for a resource.
-    # For example, let's say that you have a model &lt;tt&gt;Person&lt;/tt&gt; and want to create a new instance of it:
-    #
-    #     &lt;% form_for :person, :action =&gt; url(:people) do %&gt;
-    #       &lt;%= text_control :first_name, :label =&gt; 'First Name' %&gt;
-    #       &lt;%= text_control :last_name,  :label =&gt; 'Last Name' %&gt;
-    #       &lt;%= submit_button 'Create' %&gt;
-    #     &lt;% end %&gt;
-    #
-    # The HTML generated for this would be:
-    #
-    #     &lt;form action=&quot;/people/create&quot; method=&quot;post&quot;&gt;
-    #       &lt;label for=&quot;person_first_name&quot;&gt;First Name&lt;/label&gt;
-    #       &lt;input id=&quot;person_first_name&quot; name=&quot;person[first_name]&quot; size=&quot;30&quot; type=&quot;text&quot; /&gt;
-    #       &lt;label for=&quot;person_last_name&quot;&gt;Last Name&lt;/label&gt;
-    #       &lt;input id=&quot;person_last_name&quot; name=&quot;person[last_name]&quot; size=&quot;30&quot; type=&quot;text&quot; /&gt;
-    #       &lt;button type=&quot;submit&quot;&gt;Create&lt;/button&gt;
-    #     &lt;/form&gt;
-    #
-    # You may also create a normal form using form_tag
-    #     &lt;% form_tag(:action =&gt; url(:controller =&gt; &quot;foo&quot;, :action =&gt; &quot;bar&quot;, :id =&gt; 1)) do %&gt;
-    #       &lt;%= text_field :name =&gt; 'first_name', :label =&gt; 'First Name' %&gt;
-    #       &lt;%= submit_button 'Create' %&gt;
-    #     &lt;% end %&gt;
-    #
-    # The HTML generated for this would be:
-    #
-    #     &lt;form action=&quot;/foo/bar/1&quot; method=&quot;post&quot;&gt;
-    #       &lt;label for=&quot;first_name&quot;&gt;First Name&lt;/label&gt;&lt;input id=&quot;first_name&quot; name=&quot;first_name&quot; size=&quot;30&quot; type=&quot;text&quot; /&gt;
-    #       &lt;button type=&quot;submit&quot;&gt;Create&lt;/button&gt;
-    #     &lt;/form&gt;
-    module Form
-    
-      # Provides a HTML formatted display of resource errors in an unordered list with a h2 form submission error
-      # ==== Options
-      # +build_li+:: Block for generating a list item for an error. It receives an instance of the error.
-      # +html_class+:: Set for custom error div class default is &lt;tt&gt;submission_failed&lt;tt&gt;
-      #
-      # ==== Examples
-      #   &lt;%= error_messages_for :person %&gt;
-      #   &lt;%= error_messages_for :person {|errors| &quot;You can has probs nao: #{errors.size} of em!&quot;}
-      #   &lt;%= error_messages_for :person, lambda{|error| &quot;&lt;li class='aieeee'&gt;#{error.join(' ')}&quot;} %&gt;
-      #   &lt;%= error_messages_for :person, nil, 'bad_mojo' %&gt;
-      def error_messages_for(obj, build_li = nil, html_class='error')
-        obj = self.instance_variable_get(&quot;@#{obj}&quot;) if obj.kind_of?(Symbol)
-        
-        return &quot;&quot; unless obj.respond_to?(:errors) &amp;&amp; ! obj.errors.empty?
-        
-        if obj.errors.respond_to?(:each) # AR &amp; DM
-          build_li ||= lambda{|err| &quot;&lt;li&gt;#{err.join(' ')}&lt;/li&gt;&quot;}
-          error_collection = obj.errors
-        else # Sequel
-          build_li ||= lambda{|msg| &quot;&lt;li&gt;#{msg}&lt;/li&gt;&quot;}
-          error_collection = obj.errors.full_messages
-        end
-        error_count = error_collection.size
-
-        header_message = if block_given?
-          yield(obj.errors)
-        else
-          error_plurality = (error_count == 1 ? 'problem' : 'problems')
-          &quot;&lt;h2&gt;Form submission failed because of #{error_count} #{error_plurality}&lt;/h2&gt;&quot;
-        end
-        
-        markup = %Q{
-          &lt;div class='#{html_class}'&gt;
-            #{header_message}
-            &lt;ul&gt;
-        }
-        
-        error_collection.each {|error, message| markup &lt;&lt; build_li.call([error, message])}
-
-        markup &lt;&lt; %Q{
-            &lt;/ul&gt;
-          &lt;/div&gt;
-        }
-      end
-      
-      def obj_from_ivar_or_sym(obj) 
-        obj.is_a?(Symbol) ? instance_variable_get(&quot;@#{obj}&quot;) : obj
-      end
-      
-      # Generates a form tag, which accepts a block that is not directly based on resource attributes
-      # 
-      #     &lt;% form_tag(:action =&gt; url(:controller =&gt; &quot;foo&quot;, :action =&gt; &quot;bar&quot;, :id =&gt; 1)) do %&gt;
-      #       &lt;%= text_field :name =&gt; 'first_name', :label =&gt; 'First Name' %&gt;
-      #       &lt;%= submit_button 'Create' %&gt;
-      #     &lt;% end %&gt;
-      #
-      # The HTML generated for this would be:
-      #
-      #     &lt;form action=&quot;/foo/bar/1&quot; method=&quot;post&quot;&gt;
-      #       &lt;label for=&quot;first_name&quot;&gt;First Name&lt;/label&gt;&lt;input id=&quot;first_name&quot; name=&quot;first_name&quot; size=&quot;30&quot; type=&quot;text&quot; /&gt;
-      #       &lt;input name=&quot;commit&quot; type=&quot;submit&quot; value=&quot;Create&quot; /&gt;
-      #     &lt;/form&gt;
-      def form_tag(attrs = {}, &amp;block)
-        set_multipart_attribute!(attrs)
-        fake_form_method = set_form_method(attrs)
-        concat(open_tag(&quot;form&quot;, attrs), block.binding)
-        concat(generate_fake_form_method(fake_form_method), block.binding) if fake_form_method
-        concat(capture(&amp;block), block.binding)
-        concat(&quot;&lt;/form&gt;&quot;, block.binding)
-      end
-      
-      # Generates a resource specific form tag which accepts a block, this also provides automatic resource routing.
-      #     &lt;% form_for :person, :action =&gt; url(:people) do %&gt;
-      #       &lt;%= text_control :first_name, :label =&gt; 'First Name' %&gt;
-      #       &lt;%= text_control :last_name,  :label =&gt; 'Last Name' %&gt;
-      #       &lt;%= submit_button 'Create' %&gt;
-      #     &lt;% end %&gt;
-      #
-      # The HTML generated for this would be:
-      #
-      #     &lt;form action=&quot;/people/create&quot; method=&quot;post&quot;&gt;
-      #       &lt;label for=&quot;person[first_name]&quot;&gt;First Name&lt;/label&gt;&lt;input id=&quot;person_first_name&quot; name=&quot;person[first_name]&quot; size=&quot;30&quot; type=&quot;text&quot; /&gt;
-      #       &lt;label for=&quot;person[last_name]&quot;&gt;Last Name&lt;/label&gt;&lt;input id=&quot;person_last_name&quot; name=&quot;person[last_name]&quot; size=&quot;30&quot; type=&quot;text&quot; /&gt;
-      #       &lt;input name=&quot;commit&quot; type=&quot;submit&quot; value=&quot;Create&quot; /&gt;
-      #     &lt;/form&gt;
-      def form_for(obj, attrs={}, &amp;block)
-        set_multipart_attribute!(attrs)
-        obj = obj_from_ivar_or_sym(obj)
-        fake_form_method = set_form_method(attrs, obj)
-        concat(open_tag(&quot;form&quot;, attrs), block.binding)
-        concat(generate_fake_form_method(fake_form_method), block.binding) if fake_form_method
-        fields_for(obj, attrs, &amp;block)
-        concat(&quot;&lt;/form&gt;&quot;, block.binding)
-      end
-      
-      # Creates a scope around a specific resource object like form_for, but doesnt create the form tags themselves.
-      # This makes fields_for suitable for specifying additional resource objects in the same form. 
-      #
-      # ==== Examples
-      #     &lt;% form_for :person, :action =&gt; url(:people) do %&gt;
-      #       &lt;%= text_control :first_name, :label =&gt; 'First Name' %&gt;
-      #       &lt;%= text_control :last_name,  :label =&gt; 'Last Name' %&gt;
-      #       &lt;% fields_for :permission do %&gt;
-      #         &lt;%= checkbox_control :is_admin, :label =&gt; 'Administrator' %&gt;
-      #       &lt;% end %&gt;
-      #       &lt;%= submit_button 'Create' %&gt;
-      #     &lt;% end %&gt;
-      def fields_for(obj, attrs=nil, &amp;block)
-        @_obj ||= nil
-        @_block ||= nil
-        @_object_name ||= nil
-        obj = obj_from_ivar_or_sym(obj)
-        old_obj, @_obj = @_obj, obj
-        old_block, @_block = @_block, block
-        old_object_name, @_object_name = @_object_name, &quot;#{@_obj.class}&quot;.snake_case
-        
-        concat(capture(&amp;block), block.binding)
-
-        @_obj, @_block, @_object_name = old_obj, old_block, old_object_name
-      end
-      
-      def control_name(col)
-        &quot;#{@_object_name}[#{col}]&quot;
-      end
-      
-      def control_id(col)
-        &quot;#{@_object_name}_#{col}&quot;
-      end
-      
-      def control_value(col)
-        escape_xml(@_obj.send(col))
-      end
-      
-      def control_name_value(col, attrs)
-        {:name =&gt; control_name(col), :value =&gt; control_value(col)}.merge(attrs)
-      end
-      
-      # Provides a HTML text input tag based on a resource attribute.
-      #
-      # ==== Example
-      #     &lt;% form_for :person, :action =&gt; url(:people) do %&gt;
-      #       &lt;%= text_control :first_name, :label =&gt; 'First Name' %&gt;
-      #     &lt;% end %&gt;
-      def text_control(col, attrs = {})
-        errorify_field(attrs, col)
-        attrs.merge!(:id =&gt; control_id(col))
-        text_field(control_name_value(col, attrs))
-      end
-      
-      # Provides a generic HTML text input tag.
-      # Provides a HTML text input tag based on a resource attribute.
-      #
-      # ==== Example
-      #     &lt;%= text_field :name =&gt; :fav_color, :label =&gt; 'Your Favorite Color' %&gt;
-      #     # =&gt; &lt;label for=&quot;fav_color&quot;&gt;Your Favorite Color&lt;/label&gt;&lt;input type=&quot;text&quot; name=&quot;fav_color&quot; id=&quot;fav_color&quot;/&gt;
-      def text_field(attrs = {})
-        attrs.merge!(:type =&gt; &quot;text&quot;)
-        attrs.add_html_class!(&quot;text&quot;)
-        optional_label(attrs) { self_closing_tag(&quot;input&quot;, attrs) }
-      end
-      
-      # Provides a HTML password input based on a resource attribute.
-      # This is generally used within a resource block such as +form_for+.
-      #
-      # ==== Example
-      #     &lt;%= password_control :password, :label =&gt; 'New Password' %&gt;
-      def password_control(col, attrs = {})
-        attrs.merge!(:name =&gt; control_name(col), :id =&gt; control_id(col))
-        errorify_field(attrs, col)
-        password_field({:name =&gt; control_name(col)}.merge(attrs))
-      end
-      
-      # Provides a generic HTML password input tag.
-      #
-      # ==== Example
-      #     &lt;%= password_field :name =&gt; :password, :label =&gt; &quot;Password&quot; %&gt;
-      #     # =&gt; &lt;label for=&quot;password&quot;&gt;Password&lt;/label&gt;&lt;input type=&quot;password&quot; name=&quot;password&quot; id=&quot;password&quot;/&gt;
-      def password_field(attrs = {})
-        attrs.merge!(:type =&gt; 'password')
-        attrs.add_html_class!(&quot;password&quot;)
-        optional_label(attrs) { self_closing_tag(&quot;input&quot;, attrs) }
-      end
-      
-      # translate column values from the db to boolean
-      # nil, false, 0 and '0' are false. All others are true
-      def col_val_to_bool(val)
-        !(val == &quot;0&quot; || val == 0 || !val)
-      end
-      private :col_val_to_bool
-
-      # Provides a HTML checkbox input based on a resource attribute.
-      # This is generally used within a resource block such as +form_for+.
-      #
-      # ==== Example
-      #     &lt;%= checkbox_control :is_activated, :label =&gt; &quot;Activated?&quot; %&gt;
-      def checkbox_control(col, attrs = {}, hidden_attrs={})
-        errorify_field(attrs, col)
-        method_name = @_obj.respond_to?(col) ? col : :&quot;#{col}?&quot;
-        attrs.merge!(:checked =&gt; &quot;checked&quot;) if col_val_to_bool(@_obj.send(method_name))
-        attrs.merge!(:id =&gt; control_id(col))
-        attrs = {:name =&gt; control_name(col), :value =&gt; control_value(method_name)}.merge(attrs)
-        checkbox_field(attrs, hidden_attrs)
-      end
-
-      # Provides a generic HTML checkbox input tag.
-      # There are two ways this tag can be generated, based on the
-      # option :boolean. If not set to true, a &quot;magic&quot; input is generated.
-      # Otherwise, an input is created that can be easily used for passing
-      # an array of values to the application.
-      #
-      # ==== Example
-      #     &lt;% checkbox_field :name =&gt; &quot;is_activated&quot;, :value =&gt; &quot;1&quot; %&gt;
-      #
-      #     &lt;% checkbox_field :name =&gt; &quot;choices[]&quot;, :boolean =&gt; false, :value =&gt; &quot;dog&quot; %&gt;
-      #     &lt;% checkbox_field :name =&gt; &quot;choices[]&quot;, :boolean =&gt; false, :value =&gt; &quot;cat&quot; %&gt;
-      #     &lt;% checkbox_field :name =&gt; &quot;choices[]&quot;, :boolean =&gt; false, :value =&gt; &quot;weasle&quot; %&gt;
-      def checkbox_field(attrs = {}, hidden_attrs={})
-        boolbox = true
-        boolbox = false if ( attrs.has_key?(:boolean) and !attrs[:boolean] )
-        attrs.delete(:boolean)
-
-        if( boolbox )
-                on            = attrs.delete(:on)  || 1
-                off           = attrs.delete(:off) || 0
-                attrs[:value] = on if ( (v = attrs[:value]).nil? || v != &quot;&quot; )
-        else
-                # HTML-escape the value attribute
-                attrs[:value] = escape_xml( attrs[:value] )
-        end
-
-        attrs.merge!(:type =&gt; :checkbox)
-        attrs.add_html_class!(&quot;checkbox&quot;)
-        (boolbox ? hidden_field({:name =&gt; attrs[:name], :value =&gt; off}.merge(hidden_attrs)) : '') + optional_label(attrs){self_closing_tag(&quot;input&quot;, attrs)}
-      end
-
-      # Returns a hidden input tag tailored for accessing a specified attribute (identified by +col+) on an object
-      # resource within a +form_for+ resource block. Additional options on the input tag can be passed as a
-      # hash with +attrs+. These options will be tagged onto the HTML as an HTML element attribute as in the example
-      # shown.
-      #
-      # ==== Example
-      #     &lt;%= hidden_control :identifier %&gt;
-      #     # =&gt; &lt;input id=&quot;person_identifier&quot; name=&quot;person[identifier]&quot; type=&quot;hidden&quot; value=&quot;#{@person.identifier}&quot; /&gt;
-      def hidden_control(col, attrs = {})
-        attrs.delete(:label)
-        errorify_field(attrs, col)
-        attrs[:class] ||= &quot;hidden&quot;
-        hidden_field(control_name_value(col, attrs))
-      end
-      
-      # Provides a generic HTML hidden input field.
-      #
-      # ==== Example
-      #     &lt;%= hidden_field :name =&gt; &quot;secret&quot;, :value =&gt; &quot;some secret value&quot; %&gt;
-      def hidden_field(attrs = {})
-        attrs.delete(:label)
-        attrs.merge!(:type =&gt; :hidden)
-        attrs.add_html_class!(&quot;hidden&quot;)
-        self_closing_tag(&quot;input&quot;, attrs)
-      end
-      
-      # Provides a HTML radio input tag based on a resource attribute.
-      #
-      # ==== Example
-      #     &lt;% form_for :person, :action =&gt; url(:people) do %&gt;
-      #       &lt;%= radio_control :first_name %&gt;
-      #     &lt;% end %&gt;
-      def radio_control(col, attrs = {})
-        errorify_field(attrs, col)
-        attrs.merge!(:id =&gt; control_id(col))
-        val = @_obj.send(col)
-        attrs.merge!(:checked =&gt; &quot;checked&quot;) if val.to_s == attrs[:value]
-        optional_label(attrs) { radio_field(control_name_value(col, attrs)) }
-      end
-
-      # Provides a radio group based on a resource attribute.
-      # This is generally used within a resource block such as +form_for+.
-      #
-      # ==== Examples
-      #     &lt;%# the labels are the options %&gt;
-      #     &lt;%= radio_group_control :my_choice, [5,6,7] %&gt;
-      # 
-      #     &lt;%# custom labels %&gt;
-      #     &lt;%= radio_group_control :my_choice, [{:value =&gt; 5, :label =&gt; &quot;five&quot;}] %&gt;
-      def radio_group_control(col, options = [], attrs = {})
-        errorify_field(attrs, col)
-        val = @_obj.send(col)
-        ret = &quot;&quot;
-        options.each do |opt|
-          value, label = opt.is_a?(Hash) ? [opt.delete(:value), opt.delete(:label)] : [opt, opt]
-          hash = {:name =&gt; &quot;#{@_object_name}[#{col}]&quot;, :value =&gt; value, :label =&gt; label, :id =&gt; &quot;#{control_id(col)}_#{value}&quot; }
-          hash.merge!(opt) if opt.is_a?(Hash)
-          hash.merge!(:checked =&gt; &quot;checked&quot;) if val.to_s == value.to_s
-          ret &lt;&lt; radio_field(hash)
-        end
-        ret
-      end
-      
-      # Provides a generic HTML radio input tag.
-      # Normally, you would use multipe +radio_field+.
-      #
-      # ==== Example
-      #     &lt;%= radio_field :name =&gt; &quot;radio_options&quot;, :value =&gt; &quot;1&quot;, :label =&gt; &quot;One&quot; %&gt;
-      #     &lt;%= radio_field :name =&gt; &quot;radio_options&quot;, :value =&gt; &quot;2&quot;, :label =&gt; &quot;Two&quot; %&gt;
-      #     &lt;%= radio_field :name =&gt; &quot;radio_options&quot;, :value =&gt; &quot;3&quot;, :label =&gt; &quot;Three&quot;, :checked =&gt; true %&gt;
-      def radio_field(attrs = {})
-        attrs.merge!(:type =&gt; &quot;radio&quot;)
-        attrs.delete(:checked) unless attrs[:checked]
-        attrs.add_html_class!(&quot;radio&quot;)
-        optional_label(attrs){self_closing_tag(&quot;input&quot;, attrs)}
-      end
-      
-      # Provides a HTML textarea based on a resource attribute
-      # This is generally used within a resource block such as +form_for+
-      #
-      # ==== Example
-      #     &lt;% text_area_control :comments, :label =&gt; &quot;Comments&quot;
-      def text_area_control(col, attrs = {})
-        attrs ||= {}
-        errorify_field(attrs, col)
-        attrs.merge!(:id =&gt; control_id(col))
-        text_area_field(control_value(col), attrs.merge(:name =&gt; control_name(col)))
-      end
-      
-      # Provides a generic HTML textarea tag.
-      #
-      # ==== Example
-      #     &lt;% text_area_field &quot;my comments&quot;, :name =&gt; &quot;comments&quot;, :label =&gt; &quot;Comments&quot; %&gt;
-      def text_area_field(val, attrs = {})
-        val ||=&quot;&quot;
-        optional_label(attrs) do
-          open_tag(&quot;textarea&quot;, attrs) +
-          val +
-          &quot;&lt;/textarea&gt;&quot;
-        end
-      end
-      
-      # Provides a generic HTML submit button.
-      #
-      # ==== Example
-      #     &lt;% submit_button &quot;Process&quot; %&gt;
-      def submit_button(contents, attrs = {})
-        contents ||= &quot;Submit&quot;
-        attrs.merge!(:type =&gt; &quot;submit&quot;)
-        tag(&quot;button&quot;, contents, attrs)
-      end
-
-      # Provides a generic HTML label.
-      #
-      # ==== Example
-      #     &lt;% label &quot;Name&quot;, &quot;&quot;, :for =&gt; &quot;name&quot; %&gt; 
-      #     # =&gt; &lt;label for=&quot;name&quot;&gt;Name&lt;/label&gt;
-      def label(name, contents = &quot;&quot;, attrs = {})
-        tag(&quot;label&quot;, name.to_s + contents, attrs)
-      end
-
-      # Provides a generic HTML select.
-      #
-      # ==== Options
-      # +prompt+:: Adds an additional option tag with the provided string with no value.
-      # +selected+:: The value of a selected object, which may be either a string or an array.
-      # +include_blank+:: Adds an additional blank option tag with no value.
-      # +collection+:: The collection for the select options
-      # +text_method+:: Method to determine text of an option (as a symbol). Ex: :text_method =&gt; :name  will call .name on your record object for what text to display.
-      # +value_method+:: Method to determine value of an option (as a symbol).
-      def select_field(attrs = {})
-        collection = attrs.delete(:collection)
-        option_attrs = {
-          :prompt =&gt; attrs.delete(:prompt),
-          :selected =&gt; attrs.delete(:selected),
-          :include_blank =&gt; attrs.delete(:include_blank),
-          :text_method =&gt; attrs.delete(:text_method),
-          :value_method =&gt; attrs.delete(:value_method)
-        }
-        optional_label(attrs) { open_tag('select', attrs) + options_from_collection_for_select(collection, option_attrs) + &quot;&lt;/select&gt;&quot;}
-      end
-      
-      # Provides a HTML select based on a resource attribute.
-      # This is generally used within a resource block such as +form_for+.
-      #
-      # ==== Example
-      #     &lt;% select_control :name, :collection =&gt; %w(one two three four) %&gt;
-      def select_control(col, attrs = {})
-        attrs.merge!(:name =&gt; attrs[:name] || control_name(col))
-        attrs.merge!(:id   =&gt; attrs[:id]   || control_id(col))
-        attrs.merge!(:selected =&gt; attrs[:selected] || control_value(col))
-        errorify_field(attrs, col)
-        optional_label(attrs) { select_field(attrs) }
-      end
-      
-      # Accepts a collection (hash, array, enumerable, your type) and returns a string of option tags. 
-      # Given a collection where the elements respond to first and last (such as a two-element array), 
-      # the &quot;lasts&quot; serve as option values and the &quot;firsts&quot; as option text. Hashes are turned into
-      # this form automatically, so the keys become &quot;firsts&quot; and values become lasts. If selected is
-      # specified, the matching &quot;last&quot; or element will get the selected option-tag. Selected may also
-      # be an array of values to be selected when using a multiple select.
-      #
-      # ==== Examples
-      #   &lt;%= options_for_select( [['apple','Apple Pie'],['orange','Orange Juice']], :selected =&gt; 'orange' )
-      #   =&gt; &lt;option value=&quot;apple&quot;&gt;Apple Pie&lt;/option&gt;&lt;option value=&quot;orange&quot; selected=&quot;selected&quot;&gt;Orange Juice&lt;/option&gt;
-      #
-      #   &lt;%= options_for_select( [['apple','Apple Pie'],['orange','Orange Juice']], :selected =&gt; ['orange','apple'], :prompt =&gt; 'Select One' )
-      #   =&gt; &lt;option value=&quot;&quot;&gt;Select One&lt;/option&gt;&lt;option value=&quot;apple&quot; selected=&quot;selected&quot;&gt;Apple Pie&lt;/option&gt;&lt;option value=&quot;orange&quot; selected=&quot;selected&quot;&gt;Orange Juice&lt;/option&gt;
-      #
-      # ==== Options
-      # +selected+:: The value of a selected object, which may be either a string or an array.
-      # +prompt+:: Adds an addtional option tag with the provided string with no value.
-      # +include_blank+:: Adds an additional blank option tag with no value.
-      def options_for_select(collection, attrs = {})
-        prompt     = attrs.delete(:prompt)
-        blank      = attrs.delete(:include_blank)
-        selected   = attrs.delete(:selected)
-        ret = String.new
-        ret &lt;&lt; tag('option', prompt, :value =&gt; '') if prompt
-        ret &lt;&lt; tag(&quot;option&quot;, '', :value =&gt; '') if blank
-        unless collection.blank?
-          if collection.is_a?(Hash)
-            collection.each do |label,group|
-              ret &lt;&lt; open_tag(&quot;optgroup&quot;, :label =&gt; label.to_s.gsub(/\b[a-z]/) {|x| x.upcase}) + 
-                options_for_select(group, :selected =&gt; selected) + &quot;&lt;/optgroup&gt;&quot;
-            end
-          else
-            collection.each do |value,text|
-              options = Array(selected).include?(value) ? {:selected =&gt; 'selected'} : {}
-              ret &lt;&lt; tag( 'option', text, {:value =&gt; value}.merge(options) )
-            end
-          end
-        end
-
-        return ret
-      end
-
-      # Returns a string of option tags that have been compiled by iterating over the collection and
-      # assigning the the result of a call to the value_method as the option value and the text_method
-      # as the option text. If selected_value is specified, the element returning a match on
-      # the value_method option will get the selected option tag.
-      #
-      # This method also also supports the automatic generation of optgroup tags by using a hash.
-      # ==== Examples
-      # If we had a collection of people within a @project object, and want to use 'id' as the value, and 'name'
-      # as the option content we could do something similar to this;
-      #
-      #   &lt;%= options_from_collection_for_select(@project.people, :value_method =&gt; &quot;id&quot;, :text_method =&gt; &quot;name&quot;) %&gt;
-      #   The iteration of the collection would create options in this manner;
-      #   =&gt;  &lt;option value=&quot;#{person.id}&quot;&gt;#{person.name}&lt;/option&gt;
-      #
-      #   &lt;% @people = Person.find(:all).group_by( &amp;:state )
-      #   &lt;%= options_for_select(@people, :text_method =&gt; 'full_name', :value_method =&gt; 'id', :selected =&gt; 3) %&gt;
-      #   =&gt; &lt;optgroup label=&quot;Washington&quot;&gt;&lt;option value=&quot;1&quot;&gt;Josh Martin&lt;/option&gt;&lt;option value=&quot;2&quot;&gt;John Doe&lt;/option&gt;&lt;/optgroup&gt;
-      #   =&gt; &lt;optgroup label=&quot;Idaho&quot;&gt;&lt;option value=&quot;3&quot; selected=&quot;selected&quot;&gt;Jane Doe&lt;/option&gt;
-      #
-      # ==== Options
-      # +text_method+:: Defines the method which will be used to provide the text of the option tags (required)
-      # +value_method+:: Defines the method which will be used to provide the value of the option tags (required)
-      # +selected+:: The value of a selected object, may be either a string or an array.
-      def options_from_collection_for_select(collection, attrs = {})
-        prompt     = attrs.delete(:prompt)
-        blank      = attrs.delete(:include_blank)
-        ret = String.new
-        if collection.is_a?(Hash)
-          ret &lt;&lt; tag(&quot;option&quot;, prompt, :value =&gt; '') if prompt
-          ret &lt;&lt; tag(&quot;option&quot;, '',     :value =&gt; '') if blank
-          collection.each do |label, group|
-            # .gsub(/_/, &quot; &quot;).gsub(/\b[a-z]/) {|x| x.upcase}) == .humanize.titleize, which is no longer in -core
-            ret &lt;&lt; open_tag(&quot;optgroup&quot;, :label =&gt; label.to_s.gsub(/_/, &quot; &quot;).gsub(/\b[a-z]/) {|x| x.upcase}) + 
-              options_from_collection_for_select(group, attrs) + &quot;&lt;/optgroup&gt;&quot;
-          end
-          return ret
-        else
-          text_method    = attrs[:text_method]
-          value_method   = attrs[:value_method]
-          selected_value = attrs[:selected]
-          
-          text_method ||= :to_s
-          value_method ||= text_method
-          
-          options_for_select((collection || []).inject([]) { |options, object| 
-              options &lt;&lt; [ object.send(value_method), object.send(text_method) ] },
-            :selected =&gt; selected_value, :include_blank =&gt; blank, :prompt =&gt; prompt
-          )
-        end
-      end
-      
-      # Provides the ability to create quick fieldsets as blocks for your forms.
-      #
-      # ==== Example
-      #     &lt;% fieldset :legend =&gt; 'Customer Options' do -%&gt;
-      #     ...your form elements
-      #     &lt;% end -%&gt;
-      #
-      #     =&gt; &lt;fieldset&gt;&lt;legend&gt;Customer Options&lt;/legend&gt;...your form elements&lt;/fieldset&gt;
-      #
-      # ==== Options
-      # +legend+:: The name of this fieldset which will be provided in a HTML legend tag.
-      def fieldset(attrs={}, &amp;block)
-        legend = attrs.delete(:legend)
-        concat( open_tag('fieldset', attrs), block.binding )
-        concat( tag('legend', legend), block.binding ) if legend
-        concat(capture(&amp;block), block.binding)
-        concat( &quot;&lt;/fieldset&gt;&quot;, block.binding)
-      end
-      
-      # Provides a HTML file input for a resource attribute.
-      # This is generally used within a resource block such as +form_for+.
-      #
-      # ==== Example
-      #     &lt;% file_control :file, :label =&gt; &quot;File&quot; %&gt;
-      def file_control(col, attrs = {})
-        errorify_field(attrs, col)
-        file_field(control_name_value(col, attrs))
-      end
-      
-      # Provides a HTML file input
-      #
-      # ==== Example
-      #     &lt;% file_field :name =&gt; &quot;file&quot;, :label =&gt; &quot;File&quot; %&gt;
-      def file_field(attrs = {})
-        attrs.merge!(:type =&gt; &quot;file&quot;)
-        attrs.add_html_class!(&quot;file&quot;)
-        optional_label(attrs) { self_closing_tag(&quot;input&quot;, attrs) }
-      end
-      
-      def submit_field(attrs = {})
-        attrs.merge!(:type =&gt; :submit)
-        attrs[:name] ||= &quot;submit&quot;
-        self_closing_tag(&quot;input&quot;, attrs)
-      end
-
-      # Generates a delete button inside of a form. 
-      # 
-      #     &lt;%= delete_button :news_post, @news_post, 'Remove' %&gt;
-      #     &lt;%= delete_button('/posts/24/comments/10') %&gt;
-      # 
-      # The HTML generated for this would be:
-      # 
-      #     &lt;form method=&quot;post&quot; action=&quot;/news_posts/4&quot;&gt;
-      #       &lt;input type=&quot;hidden&quot; value=&quot;delete&quot; name=&quot;_method&quot;/&gt;
-      #       &lt;button type=&quot;submit&quot;&gt;Remove&lt;/button&gt;
-      #     &lt;/form&gt;
-      #
-      #     &lt;form method=&quot;post&quot; action=&quot;/posts/24/comments/10&quot;&gt;
-      #       &lt;input type=&quot;hidden&quot; value=&quot;delete&quot; name=&quot;_method&quot;/&gt;
-      #       &lt;button type=&quot;submit&quot;&gt;Remove&lt;/button&gt;
-      #     &lt;/form&gt;
-      def delete_button(symbol_or_string, obj = nil, contents = 'Delete', form_attrs = {}, button_attrs = {})
-        obj ||= instance_variable_get(&quot;@#{symbol_or_string}&quot;) if symbol_or_string.kind_of?(Symbol)
-        
-        button_attrs[:type] = :submit
-        
-        form_attrs.merge! :action =&gt; symbol_or_string.kind_of?(Symbol) ? url(symbol_or_string, obj) : symbol_or_string, :method =&gt; :delete
-        
-        fake_form_method = set_form_method(form_attrs, obj)
-        
-        button = ''
-        button &lt;&lt; open_tag(:form, form_attrs)
-        button &lt;&lt; generate_fake_form_method(fake_form_method)
-        button &lt;&lt; tag(:button, contents, button_attrs)
-        button &lt;&lt; '&lt;/form&gt;'
-        button
-      end
-      
-    private
-    # Fake out the browser to send back the method for RESTful stuff.
-    # Fall silently back to post if a method is given that is not supported here
-    def set_form_method(options = {}, obj = nil)
-      options[:method] ||= ((obj &amp;&amp; obj.respond_to?(:new_record?) &amp;&amp; !obj.new_record?) ? :put : :post)
-      if ![:get,:post].include?(options[:method])
-        fake_form_method = options[:method] if [:put, :delete].include?(options[:method])
-        options[:method] = :post
-      end
-      fake_form_method
-    end
-    
-    def generate_fake_form_method(fake_form_method)
-      fake_form_method ? hidden_field(:name =&gt; &quot;_method&quot;, :value =&gt; &quot;#{fake_form_method}&quot;) : &quot;&quot;
-    end
-    
-    def optional_label(attrs = {})
-      label = attrs.delete(:label) if attrs
-      if label
-        title = label.is_a?(Hash) ? label.delete(:title) : label
-        named = attrs[:id].blank? ? {} : {:for =&gt; attrs[:id]}
-        align = label.delete(:align) if label.is_a?(Hash)
-        align ||= ['radio', 'checkbox'].include?(attrs[:type].to_s) ? :right : :left
-        label_tag = label(title, '', label.is_a?(Hash) ? label.merge(named) : named)
-        if align &amp;&amp; align.to_sym == :right
-          yield + label_tag
-        else
-          label_tag + yield
-        end
-      else
-        yield
-      end
-    end
-    
-    def errorify_field(attrs, col)
-      attrs.add_html_class!(&quot;error&quot;) if @_obj.respond_to?(:errors) &amp;&amp; @_obj.errors.on(col)
-    end   
-    
-    def set_multipart_attribute!(attrs = {})
-      attrs.merge!( :enctype =&gt; &quot;multipart/form-data&quot; ) if attrs.delete(:multipart)      
-    end
-      
-    end
-  end
-end
+load File.dirname(__FILE__) / &quot;form&quot; / &quot;helpers.rb&quot;
+load File.dirname(__FILE__) / &quot;form&quot; / &quot;builder.rb&quot;
 
 class Merb::Controller
+  class_inheritable_accessor :_form_class
   include Merb::Helpers::Form
 end
+
+Merb::BootLoader.after_app_loads do
+  class Merb::Controller
+    self._form_class =
+      Object.full_const_get(Merb::Plugins.config[:helpers][:form_class]) rescue Merb::Helpers::Form::Builder::FormWithErrors
+  end
+end</diff>
      <filename>merb_helpers/lib/merb_helpers/form_helpers.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,6 +1,8 @@
 require File.dirname(__FILE__) + '/spec_helper'
 
 describe &quot;relative_date&quot; do
+  include Merb::Helpers::DateAndTime  
+  
   before :each do
     Time.stub!(:now).and_return(Time.utc(2007, 6, 1, 11))
   end
@@ -27,6 +29,8 @@ describe &quot;relative_date&quot; do
 end
 
 describe &quot;relative_date_span&quot; do
+  include Merb::Helpers::DateAndTime  
+  
   before :each do
     Time.stub!(:now).and_return(Time.utc(2007, 6, 1, 11))
   end
@@ -66,6 +70,8 @@ describe &quot;relative_date_span&quot; do
 end
 
 describe &quot;relative_time_span&quot; do
+  include Merb::Helpers::DateAndTime  
+  
   before :each do
     Time.stub!(:now).and_return(Time.utc(2007, 6, 1, 11))
   end
@@ -105,6 +111,8 @@ describe &quot;relative_time_span&quot; do
 end
 
 describe &quot;time_lost_in_words&quot; do
+  include Merb::Helpers::DateAndTime  
+  
   it &quot;Should show seconds&quot; do
     time_lost_in_words(Time.now, Time.now, true).should == &quot;less than 5 seconds&quot;
   end
@@ -151,6 +159,8 @@ describe &quot;time_lost_in_words&quot; do
 end
 
 describe &quot;prettier_time&quot; do
+  include Merb::Helpers::DateAndTime  
+  
   # prettier time&quot;
   it &quot;Should not show leading zero in hour&quot; do
     prettier_time(Time.utc(2007, 11, 15, 14, 0)).should == '2:00 PM'</diff>
      <filename>merb_helpers/spec/merb_helpers_date_time_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -4,10 +4,6 @@ require 'rubygems'
 require 'merb-core'
 require 'merb_helpers'
 Merb::Helpers.load
-include Merb::Helpers::DateAndTime
-include Merb::ControllerMixin
-include Merb::Helpers::Tag
-include Merb::Helpers::Form
 
 def unload_merb_helpers
   Merb.class_eval do
@@ -29,13 +25,23 @@ class FakeDMModel
     ]
   end
   
+  def new_record?
+    false
+  end
+  
+  def errors
+    FakeErrors.new(self)
+  end
+  
   def baz?
     true
   end
+  alias baz baz?
   
   def bat?
     false
   end
+  alias bat bat?
 end
 
 
@@ -341,7 +347,14 @@ module Merb
   end
 end
 
-describe &quot;FakeBufferConsumer&quot;, :shared =&gt; true do
+describe &quot;FakeController&quot;, :shared =&gt; true do
+  class_inheritable_accessor :_form_class
+  self._form_class = Merb::Plugins.config[:helpers][:form_class]
+  include Merb::Helpers::DateAndTime
+  include Merb::ControllerMixin
+  include Merb::Helpers::Tag
+  include Merb::Helpers::Form
+  
   before :each do
     @obj = FakeModel.new
     def _buffer(buf = &quot;&quot;) @buffer ||= &quot;&quot; end</diff>
      <filename>merb_helpers/spec/spec_helper.rb</filename>
    </modified>
    <modified>
      <diff>@@ -23,14 +23,21 @@ module Merb
       self_closing_tag(:text, {:text =&gt; text}.merge(opts))
     end
     
-    def lz_window(width, height, opts = {}, &amp;blk)
-      opts = {:resizable =&gt; true, :width =&gt; width, :height =&gt; height}.merge!(opts)
+    def lz_window(width = nil, height = nil, opts = {}, &amp;blk)
+      mrg = {:resizable =&gt; true}
+      mrg.merge!(:width =&gt; width) if width
+      mrg.merge!(:height =&gt; height) if height
+      opts = mrg.merge(opts)
       tag(:window, nil, opts, &amp;blk)
     end
     
-    def lz_resource(name, src, opts = {})
+    def add_lz_resource(src)
       @lz_resources ||= []
-      @lz_resources &lt;&lt; src
+      @lz_resources &lt;&lt; src unless URI.parse(src).scheme
+    end
+    
+    def lz_resource(name, src, opts = {})
+      add_lz_resource(src)
       opts.merge!(:name =&gt; name, :src =&gt; src)
       self_closing_tag(:resource, opts)
     end
@@ -40,6 +47,25 @@ module Merb
       options.merge!(:args =&gt; args.map {|x| x.to_s}.join(&quot;, &quot;)) unless args.empty?
       tag(:handler, capture(&amp;blk), options)
     end
+    
+    def lz_attr(name, value, type = nil)
+      mrg = {:name =&gt; name, :value =&gt; value}
+      mrg.merge!(:type =&gt; type) if type
+      self_closing_tag(:attribute, mrg)
+    end
+
+    def lz_def(name, *args, &amp;blk)
+      tag(:method, blk ? capture(&amp;blk) : &quot;&quot;, :name =&gt; name, :args =&gt; args.map {|x| x.to_s}.join(&quot;,&quot;))
+    end
+    
+    def lz_view(width, height, bgcolor, options = {}, &amp;blk)
+      tag(:view, blk ? capture(&amp;blk) : &quot;&quot;, {:width =&gt; width, :height =&gt; height, :bgcolor =&gt; bgcolor}.merge(options))
+    end
+    
+    def lz_resource_view(src, options = {}, &amp;blk)
+      add_lz_resource(src)
+      tag(:view, blk ? capture(&amp;blk) : &quot;&quot;, {:resource =&gt; src}.merge(options))
+    end
   
   end
 end
\ No newline at end of file</diff>
      <filename>merb_laszlo/lib/merb-laszlo/helpers.rb</filename>
    </modified>
  </modified>
  <removed type="array">
    <removed>
      <filename>merb_helpers/spec/merb_helpers_spec.rb</filename>
    </removed>
  </removed>
  <parents type="array">
    <parent>
      <id>e258e56ddc55cf1491b84c2476449e6a5e6bf3ed</id>
    </parent>
  </parents>
  <author>
    <name>Michael Sheakoski</name>
    <email>michael@Michaels-iMac.local</email>
  </author>
  <url>http://github.com/wycats/merb-plugins/commit/3c57a1795a00ac28f50037dcaa9dc24ddf54813b</url>
  <id>3c57a1795a00ac28f50037dcaa9dc24ddf54813b</id>
  <committed-date>2008-08-13T13:54:56-07:00</committed-date>
  <authored-date>2008-08-13T13:54:56-07:00</authored-date>
  <message>Merged helpers_refactor branch into master</message>
  <tree>8483efc2892287a4d7182762bd1d6cff5780ad73</tree>
  <committer>
    <name>Michael Sheakoski</name>
    <email>michael@Michaels-iMac.local</email>
  </committer>
</commit>
