Created
April 16, 2010 14:52
-
-
Save gregbell/368505 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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