Skip to content

Instantly share code, notes, and snippets.

@gregbell
Created April 16, 2010 14:52
Show Gist options
  • Save gregbell/368505 to your computer and use it in GitHub Desktop.
Save gregbell/368505 to your computer and use it in GitHub Desktop.
class FormBuilder
attr_reader :calls
def initialize(&block)
@calls = []
@current = @calls
block.call(self)
end
def method_missing(*args, &block)
name = args.shift
@current << [name, args, []]
if block
old_current = @current
@current = @current.last.last
block.call(self)
@current = old_current
end
end
def to_erb
@indent = 0
@erb = ""
@calling_on = 'f'
@calls.each do |c|
method_to_erb(c)
end
@erb
end
def method_to_erb(c)
has_block = c[2].any?
options = c[1].last.is_a?(Hash) ? c[1].last : {}
@erb << "#{@indent.times.collect{' '}}<%#{'=' unless has_block} #{@calling_on}.#{c[0]} #{c[1].collect{|a| a.inspect}.join(', ')} #{"do" if has_block} #{"|" + options[:for].to_s + "_form|" if options[:for]} %>\n"
if has_block
old_calling_on = @calling_on
@calling_on = "#{options[:for].to_s}_form" if options[:for]
@indent += 2
c[2].each{|child| method_to_erb(child)}
@indent -= 2
@calling_on = old_calling_on
@erb << "<% end %>\n"
end
end
end
def form(&block)
FormBuilder.new(&block)
end
user = form do |f|
f.inputs "User Details" do
f.input :username
f.input :first_name
f.input :last_name
f.input :email
f.input :roles, :as => :check_boxes, :collection => lambda{ User.find(:all) }
end
f.inputs "Password" do
f.input :password, :type => :password
f.input :password_confirmation, :type => :password
end
f.inputs "Avatar", :for => :avatar do |avatar_form|
avatar_form.input :file
end
f.inputs "Admin Access", :if => lambda { current_user.has_permission?(:manage_users) } do
f.input :admin, :label => "Give user admin privileges"
end
f.buttons
end
puts "User Form:"
puts user.to_erb
puts
post = form do |f|
f.inputs :name => "Basic" do
f.input :title
f.input :body
f.input :section
f.input :publication_state, :as => :radio
f.input :category
f.input :allow_comments, :label => "Allow commenting on this article"
end
f.inputs :name => "Advanced" do
f.input :keywords, :required => false, :hint => "Example: ruby, rails, fs"
f.input :extract, :required => false
f.input :description, :required => false
f.input :url_title, :required => false
end
f.inputs :name => "Author", :for => :author do |author_form|
author_form.input :first_name
author_form.input :last_name
end
f.buttons do
f.commit_button
end
end
puts "Posts Form:"
puts post.to_erb
puts
other = form do |f|
f.inputs "Basic", :id => "basic" do
f.input :title
f.input :body
end
f.inputs :name => "Advanced Options", :id => "advanced" do
f.input :slug, :label => "URL Title", :hint => "Created automatically if left blank", :required => false
f.input :section, :as => :radio
f.input :user, :label => "Author", :label_method => :full_name
f.input :categories, :required => false
f.input :created_at, :as => :string, :label => "Publication Date", :required => false
end
f.buttons do
f.commit_button
end
end
puts "Other Form:"
puts user.to_erb
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment