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 << %{}
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