require 'facet/inflect' require 'nitro/helper/form/controls' module Nitro # A collection of useful helpers for creating and manipulating # Forms. #-- # This helper may by applied at run time so try to optimize # this. #++ module FormHelper def self.included(base) super base.send :include, XhtmlHelper end # Override these methods to customize the rendering. # # An alternative schema could be: # #
#
#{label(prop)}
#
#{html}
#
module FormBuilder class << self # Emit form prologue. def prologue '' end # Emit form epilogue. def epilogue '' end # Emit a label. def label(prop) %{} end # Emit a form element. def element(prop, html) %{

#{label(prop)}
#{html}

} end end end # Render a standard form for the given object. #-- # RETHINK this method. #++ def form_for(obj, options = {}) str = '' name = obj.class.name.underscore method = options.fetch(:method, 'post') action = options.fetch(:action, "save_#{obj.class.name.underscore}") submit = options.fetch(:submit, 'Save') cancel = options.fetch(:cancel, "#@base/#{Scaffolding.class_to_list(obj.class)}") if enctype = options.fetch(:enctype, nil) enctype_attribute = " enctype=\"#{enctype}\"" else enctype_attribute = '' for prop in obj.class.properties.values if prop.klass.ancestors.include? Og::Blob enctype_attribute = ' enctype="multipart/form-data"' end end end action = "#{@base}/#{action}" unless action =~ /\// str << %{
} str << %{} if obj.oid str << controls_for(obj, options) str << %{} str << %{ or Cancel} if cancel str << %{
} return str end # Render the controls for the given object. def controls_for(obj, options = {}) str = FormBuilder.prologue controls_for_properties(str, obj, options) controls_for_relations(str, obj, options) str << FormBuilder.epilogue return str end # Render the controls for the properties of the given object. def controls_for_properties(str, obj, options = {}) for prop in obj.class.properties.values unless options[:all] next if prop.symbol == obj.class.primary_key.symbol or prop[:control] == :none or prop[:relation] end control = Control.fetch(obj, prop, options).render str << FormBuilder.element(prop, control) end end # Render the controls for the relations of the given object. def controls_for_relations(str, obj, options = {}) for rel in obj.class.relations unless options[:all] next if rel[:control] == :none end control = Control.fetch(obj, rel, options).render str << FormBuilder.element(rel, control) end end end end # * George Moschovitis # * Chris Farmiloe # * Rob Pitt