lib/ratpack/forms.rb in BrianTheCoder-ratpack-0.2.0 vs lib/ratpack/forms.rb in BrianTheCoder-ratpack-0.2.2

- old
+ new

@@ -1,192 +1,117 @@ module RatPack module Forms - # def error_messages_for(obj = nil, opts = {}) - # current_form_context.error_messages_for(obj, opts[:error_class] || "error", - # opts[:build_li] || "<li>%s</li>", - # opts[:header] || "<h2>Form submission failed because of %s problem%s</h2>", - # opts.key?(:before) ? opts[:before] : true) - # end + def error_messages_for(obj = nil, opts = {}) + return unless obj.respond_to?(:errors) + html = tag(:h2, "Form submission failed be cause of #{obj.errors.size} #{pluralize("error",obj.errors.size)}") + obj.errors.each do |field,msg| + html << tag(:li,msg) + end + end %w(text password hidden file).each do |kind| self.class_eval <<-RUBY, __FILE__, __LINE__ + 1 def #{kind}_field(attrs) - update_unbound_controls(attrs, "#{kind}") - label = "#{kind}" == "hidden" ? "" : unbound_label(attrs) - label + self_closing_tag(:input, {:type => "#{kind}"}.merge(attrs)) + attrs[:class] = "text" if %w(text password).include?("#{kind}") + closed_form_field(:input, {:type => "#{kind}"}.merge(attrs)) end RUBY end - - def check_box(attrs) - update_unbound_controls(attrs, "checkbox") - if attrs.delete(:boolean) - on, off = attrs.delete(:on), attrs.delete(:off) - unbound_hidden_field(:name => attrs[:name], :value => off) << - self_closing_tag(:input, {:type => "checkbox", :value => on}.merge(attrs)) + unbound_label(attrs) - else - self_closing_tag(:input, {:type => "checkbox"}.merge(attrs)) + unbound_label(attrs) - end + + def text_area(attrs = {}) + form_field(:textarea, attrs.delete(:value) || "", attrs) end - + + def button(contents, attrs = {}) + form_field(:button, contents, attrs) + end + def radio_button(attrs) - update_unbound_controls(attrs, "radio") - self_closing_tag(:input, {:type => "radio"}.merge(attrs)) + unbound_label(attrs) + closed_form_field(:input, {:type => "radio"}.merge(attrs)) end def radio_group(arr, attrs = {}) arr.map do |ind_attrs| ind_attrs = {:value => ind_attrs} unless ind_attrs.is_a?(Hash) joined = attrs.merge(ind_attrs) - joined.merge!(:label => joined[:label] || joined[:value]) radio_button(joined) end.join end - def text_area(contents, attrs) - update_unbound_controls(attrs, "text_area") - unbound_label(attrs) + tag(:textarea, contents, attrs) - end - - def label(contents, attrs = {}) - if contents - if contents.is_a?(Hash) - label_attrs = contents - contents = label_attrs.delete(:title) - else - label_attrs = attrs - end - tag(:label, contents, label_attrs) + def check_box(attrs) + if attrs.delete(:boolean) + on, off = attrs.delete(:on), attrs.delete(:off) + hidden_field(:name => attrs[:name], :value => off) << + closed_form_field(:input, {:type => "checkbox", :value => on}.merge(attrs)) else - "" + closed_form_field(:input, {:type => "checkbox"}.merge(attrs)) end end def select(attrs = {}) - update_unbound_controls(attrs, "select") attrs[:name] << "[]" if attrs[:multiple] && !(attrs[:name] =~ /\[\]$/) - tag(:select, options_for(attrs), attrs) + form_field(:select, options_for(attrs), attrs) end - def button(contents, attrs) - update_unbound_controls(attrs, "button") - tag(:button, contents, attrs) - end - - def submit(value, attrs) + def submit(value, attrs = {}) attrs[:type] ||= "submit" attrs[:name] ||= "submit" attrs[:value] ||= value - update_unbound_controls(attrs, "submit") - self_closing_tag(:input, attrs) + closed_form_field(:input, attrs) end - # def form(attrs = {}, &blk) - # captured = @origin.capture(&blk) - # fake_method_tag = process_form_attrs(attrs) - # tag(:form, fake_method_tag + captured, attrs) - # end - # - # def fieldset(attrs, &blk) - # captured = @origin.capture(&blk) - # legend = (l_attr = attrs.delete(:legend)) ? tag(:legend, l_attr) : "" - # tag(:fieldset, legend + captured, attrs) - # end - private - - def process_form_attrs(attrs) - method = attrs[:method] || :post - attrs[:enctype] = "multipart/form-data" if attrs.delete(:multipart) || @multipart - method == :post || method == :get ? "" : fake_out_method(attrs, method) + + def form_field(type, content, attrs) + attrs[:id] = attrs[:name] unless attrs.has_key?(:id) + build_field(attrs) + tag(type, content, attrs) end - - # This can be overridden to use another method to fake out methods - def fake_out_method(attrs, method) - self_closing_tag(:input, :type => "hidden", :name => "_method", :value => method) + + def closed_form_field(type, attrs) + attrs[:id] = attrs[:name] unless attrs.has_key?(:id) + build_field(attrs) + self_closing_tag(type, attrs) end - def update_unbound_controls(attrs, type) - case type - when "checkbox" - update_unbound_check_box(attrs) - when "radio" - update_unbound_radio_button(attrs) - when "file" - @multipart = true - when "text","password" - attrs[:class] = "text" - end - - attrs[:disabled] ? attrs[:disabled] = "disabled" : attrs.delete(:disabled) + def build_field(attrs) + label = attrs.has_key?(:label) ? build_label(attrs) : "" + hint = attrs.has_key?(:hint) ? tag(:div,attrs.delete(:hint), :class => "hint") : "" + label + hint end - def unbound_label(attrs = {}) + def build_label(attrs) if attrs[:id] label_attrs = {:for => attrs[:id]} elsif attrs[:name] label_attrs = {:for => attrs[:name]} else label_attrs = {} end - - label_option = attrs.delete(:label) - if label_option.is_a? Hash - label(label_attrs.merge(label_option)) - else - label(label_option, label_attrs) - end + tag(:label, attrs.delete(:label), label_attrs) end - def update_unbound_check_box(attrs) - boolean = attrs[:boolean] || (attrs[:on] && attrs[:off]) ? true : false - - case - when attrs.key?(:on) ^ attrs.key?(:off) - raise ArgumentError, ":on and :off must be specified together" - when (attrs[:boolean] == false) && (attrs.key?(:on)) - raise ArgumentError, ":boolean => false cannot be used with :on and :off" - when boolean && attrs.key?(:value) - raise ArgumentError, ":value can't be used with a boolean checkbox" - end - - if attrs[:boolean] = boolean - attrs[:on] ||= "1"; attrs[:off] ||= "0" - end - - attrs[:checked] = "checked" if attrs.delete(:checked) - end - - def update_unbound_radio_button(attrs) - attrs[:checked] = "checked" if attrs.delete(:checked) - end - def options_for(attrs) blank, prompt = attrs.delete(:include_blank), attrs.delete(:prompt) b = blank || prompt ? tag(:option, prompt || "", :value => "") : "" - # yank out the options attrs - collection, selected, text_method, value_method = - attrs.extract!(:collection, :selected, :text_method, :value_method) - + collection, selected, text_method, value_method = attrs.extract!(:collection, :selected, :text_method, :value_method) # if the collection is a Hash, optgroups are a-coming if collection.is_a?(Hash) ([b] + collection.map do |g,col| - tag(:optgroup, options(col, text_method, value_method, selected), :label => g) + tag(:optgroup, select_options(col, text_method, value_method, selected), :label => g) end).join else - options(collection || [], text_method, value_method, selected, b) + select_options(collection || [], text_method, value_method, selected, b) end end - - def options(col, text_meth, value_meth, sel, b = nil) + + def select_options(col, text_meth, value_meth, sel, b = nil) ([b] + col.map do |item| text_meth = text_meth && item.respond_to?(text_meth) ? text_meth : :last value_meth = value_meth && item.respond_to?(value_meth) ? value_meth : :first - + text = item.is_a?(String) ? item : item.send(text_meth) value = item.is_a?(String) ? item : item.send(value_meth) - + option_attrs = {:value => value} if sel.is_a?(Array) option_attrs.merge!(:selected => "selected") if value.in? sel else option_attrs.merge!(:selected => "selected") if value == sel \ No newline at end of file