ActiveForm provides a DSL for defining complete XHTML forms with validation. You can compose your own widgets and (nested) form sections from basic elements. Markup is generated by Builder, using several wrappers and callbacks which render their child elements accordingly. This allows one to customize all output.
Both serverside as well as clientside validation is supported and values are bound in a nested fashion to their elements, similar to how Rails expects params from forms.
It’s possible to output elements, sections and the complete forms, allowing easy integration with ERB templates. While it’s distributed as a gem it can easily be used as a plugin for Rails.
example: how to create a contact form in Rails
documentation: autogenerated rdocs
see rubyforge.org for more information. install as a gem: sudo gem install active_form
# sample001.html: compose a new form from scratch - see also: sample002.html sample003.html
form = ActiveForm::compose :myform, :client_side => true do |f|
f.section :person, :label => 'Your details' do |s|
s.text_element :first_name, :required => true
s.text_element :last_name, :required => true
s.password_element :password, :required => true
s.password_element :password_confirm, :required => true
s.select_element :country do |e|
e.empty = 'choose a country:'
e.options = [['Nederland', 'nl'], ['Belgiƫ', 'be']]
e.element_wrapper = side_by_side_wrap
end
s.submit_element, :label => 'Send', :element_wrapper => no_label_wrap
s.after_validation do |elem|
elem.remove_element :password_confirm if elem.valid?
end
end
f.section :message, :label => 'Your message' do |s|
s.text_element :subject, :required => true, :element_wrapper => side_by_side_wrap
s.textarea_element :message, :required => true, :rows => 5, :cols => 10 do |e|
e.after_validation do |elem|
elem.frozen_value = elem.formatted_value.word_truncate(32) if elem.valid?
end
end
s.submit_element, :label => 'Send', :element_wrapper => no_label_wrap
end
f.after_validation do |elem|
if elem.valid?
remove_elements_of_type :submit, :button
elem.freeze!
else
elem.css_style << 'border: 1px solid red'
end
end
end
# plain_view.html: create a form definition and use the plain view renderer
ActiveForm::Definition.create :sample do |f|
f.client_side = true
f.section :person, :label => 'Your details' do |s|
s.text_element :first_name, :required => true
s.text_element :last_name, :required => true
s.password_element :password, :required => true
s.password_element :password_confirm, :required => true
s.select_element :country do |e|
e.empty = 'choose a country:'
e.options = [['Nederland', 'nl'], ['Belgiƫ', 'be']]
end
s.submit_element :label => 'Send'
s.after_validation do |elem|
elem.remove_element :password_confirm if elem.valid?
end
end
f.section :message, :label => 'Your message' do |s|
s.text_element :subject, :required => true
s.textarea_element :message, :required => true, :rows => 5, :cols => 10
s.submit_element :label => 'Send'
end
f.after_validation do |elem|
if elem.valid?
remove_elements_of_type :submit, :button
elem.disabled = true
end
end
end
form = ActiveForm::Definition.build :sample, :my_form, :label => 'Plain View Sample'
# example of Rails integration; shown as unit test (currently more than 420 tests and 1900 assertions)
form = ActiveForm::Model::build(Book.new)
assert_kind_of ActiveForm::Definition, form
form.submit_element
names = form.collect(&:name)
assert_equal [:id, :title, :isbn, :publication_date, :publisher_id, :created_at, :updated_at, :submit], names
labels = form.collect(&:label)
assert_equal ["Id", "Title", "Isbn", "Publication date", "Publisher", "Created at", "Updated at", "Submit"], labels
types = form.collect(&:element_type)
assert_equal [:hidden, :text, :text, :select_date, :select_from_model, :select_datetime, :select_datetime, :submit], types
type_casting = form.collect(&:type_cast)
assert_equal [:integer, :string, :string, :date, :integer, :time, :time, nil], type_casting
# ActiveForm Copyright (c) 2007-2008 atelierfabien - loobmedia
# released under MIT license