Skip to content

Commit

Permalink
Merge 19df61b into c5cee43
Browse files Browse the repository at this point in the history
  • Loading branch information
jodosha committed Feb 23, 2015
2 parents c5cee43 + 19df61b commit e95a758
Show file tree
Hide file tree
Showing 14 changed files with 1,860 additions and 5 deletions.
5 changes: 3 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ unless ENV['TRAVIS']
gem 'yard', require: false
end

gem 'lotus-utils', github: 'lotus/utils', branch: 'master' # FIXME use a stable branch
gem 'lotus-view', github: 'lotus/view', branch: '0.3.x'
gem 'lotus-utils', github: 'lotus/utils', branch: 'master' # FIXME use a stable branch
gem 'lotus-controller', github: 'lotus/controller', branch: 'master' # FIXME use a stable branch
gem 'lotus-view', github: 'lotus/view', branch: '0.3.x'

gem 'simplecov', require: false
gem 'coveralls', require: false
2 changes: 2 additions & 0 deletions lib/lotus/helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
require 'lotus/helpers/html_helper'
require 'lotus/helpers/escape_helper'
require 'lotus/helpers/routing_helper'
require 'lotus/helpers/form_helper'

module Lotus
# View helpers for Ruby applications
Expand All @@ -21,6 +22,7 @@ def self.included(base)
include Lotus::Helpers::HtmlHelper
include Lotus::Helpers::EscapeHelper
include Lotus::Helpers::RoutingHelper
include Lotus::Helpers::FormHelper
end
end
end
Expand Down
249 changes: 249 additions & 0 deletions lib/lotus/helpers/form_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
require 'lotus/helpers/form_helper/form_builder'

module Lotus
module Helpers
# Form builder
#
# By including <tt>Lotus::Helpers::FormHelper</tt> it will inject one public method: <tt>form_for</tt>.
# This is a HTML5 form builder.
#
# To understand the general HTML5 builder syntax of this framework, please
# consider to have a look at <tt>Lotus::Helpers::HtmlHelper</tt> documentation.
#
# This builder is independent from any template engine.
# This was hard to achieve without a compromise: the form helper should be
# used in one output block in a template or as a method in a view (see the examples below).
#
# Features:
#
# * Support for complex markup without the need of concatenation
# * Auto closing HTML5 tags
# * Support for view local variables
# * Method override support (PUT/PATCH/DELETE HTTP verbs aren't understood by browsers)
# * Automatic generation of HTML attributes for inputs: <tt>id</tt>, <tt>name</tt>, <tt>value</tt>
# * Allow to override HTML attributes
# * Extract values from request params and fill <tt>value</tt> attributes
# * Automatic selection of current value for radio button and select inputs
# * Infinite nested fields
#
# Supported tags and inputs:
#
# * <tt>color_field</tt>
# * <tt>date_field</tt>
# * <tt>datetime_field</tt>
# * <tt>datetime_local_field</tt>
# * <tt>email_field</tt>
# * <tt>hidden_field</tt>
# * <tt>file_field</tt>
# * <tt>fields_for</tt>
# * <tt>form_for</tt>
# * <tt>label</tt>
# * <tt>text_field</tt>
# * <tt>radio_button</tt>
# * <tt>select</tt>
# * <tt>submit</tt>
#
# @since x.x.x
#
# @see Lotus::Helpers::FormHelper#form_for
# @see Lotus::Helpers::HtmlHelper
#
# @example One output block (template)
# <%=
# form_for :book, routes.books_path do
# text_field :title
#
# submit 'Create'
# end
# %>
#
# @example Method (view)
# require 'lotus/helpers'
#
# class MyView
# include Lotus::Helpers::FormHelper
#
# def my_form
# form_for :book, routes.books_path do
# text_field :title
# end
# end
# end
#
# # Corresponding template:
# #
# # <%= my_form %>
module FormHelper
# Default HTTP method for form
#
# @since x.x.x
# @api private
DEFAULT_METHOD = 'POST'.freeze

# Instantiate a HTML5 form builder
#
# @param name [Symbol] the toplevel name of the form, it's used to generate
# input names, ids, and to lookup params to fill values.
# @param url [String] the form action URL
# @param attributes [Hash] HTML attributes to pass to the form tag
# @param blk [Proc] A block that describes the contents of the form
#
# @return [Lotus::Helpers::FormHelper::FormBuilder] the form builder
#
# @since x.x.x
#
# @see Lotus::Helpers::FormHelper
# @see Lotus::Helpers::FormHelper::FormBuilder
#
# @example Basic usage
# <%=
# form_for :book, routes.books_path, class: 'form-horizontal' do
# div do
# label :title
# text_field :title, class: 'form-control'
# end
#
# submit 'Create'
# end
# %>
#
# Output:
# # <form action="/books" id="book-form" method="POST" class="form-horizontal">
# # <div>
# # <label for="book-title">Title</label>
# # <input type="text" name="book[title]" id="book-title" value="Test Driven Development">
# # </div>
# #
# # <button type="submit">Create</button>
# # </form>
#
# @example Method override
# <%=
# form_for :book, routes.book_path(id: book.id), method: :put do
# text_field :title
#
# submit 'Update'
# end
# %>
#
# Output:
# # <form action="/books/23" id="book-form" method="POST">
# # <input type="hidden" name="_method" value="PUT">
# # <input type="text" name="book[title]" id="book-title" value="Test Driven Development">
# #
# # <button type="submit">Update</button>
# # </form>
#
# @example Nested fields
# <%=
# form_for :delivery, routes.deliveries_path do
# text_field :customer_name
#
# fields_for :address do
# text_field :city
# end
#
# submit 'Create'
# end
# %>
#
# Output:
# # <form action="/deliveries" id="delivery-form" method="POST">
# # <input type="text" name="delivery[customer_name]" id="delivery-customer-name" value="">
# # <input type="text" name="delivery[address][city]" id="delivery-address-city" value="">
# #
# # <button type="submit">Create</button>
# # </form>
#
# @example Form to create a new resource
# <%=
# form_for :book, routes.books_path do
# text_field :title
#
# submit 'Create'
# end
# %>
#
# Output:
# # <form action="/books" id="book-form" method="POST">
# # <input type="text" name="book[title]" id="book-title" value="Test Driven Development">
# #
# # <button type="submit">Create</button>
# # </form>
#
# @example Form to update an existing resource
# <%=
# form_for { book: book }, routes.book_path(id: book.id) do
# text_field :title
#
# submit 'Update'
# end
# %>
#
# Output:
# # <form action="/books/23" id="book-form" method="POST">
# # <input type="hidden" name="_method" value="PUT">
# # <input type="text" name="book[title]" id="book-title" value="Test Driven Development">
# #
# # <button type="submit">Update</button>
# # </form>
#
# @example Share markup betweek new and update forms
# module Deliveries
# class New
# include Lotus::View
# include Lotus::Helpers
#
# def form_values
# :delivery
# end
#
# def form_action
# routes.deliveries_path
# end
# end
#
# class Edit
# include Lotus::View
# include Lotus::Helpers
#
# def form_values
# { delivery: delivery }
# end
#
# def form_action
# routes.delivery_path(id: delivery.id)
# end
# end
# end
#
# # deliveries/_form.html.erb
# <%=
# form_for form_values, form_action do
# text_field :title
#
# submit update? ? 'Update' : 'Create'
# end
# %>
#
# # deliveries/new.html.erb
# <%= render partial: 'deliveries/form' %>
#
# # deliveries/edit.html.erb
# <%= render partial: 'deliveries/form' %>
def form_for(name, url, attributes = {}, &blk)
name, values = case name
when Hash
[name.first.first, name]
else
[name, {}]
end

verb = :patch if values.any?
attributes = { action: url, id: "#{ name }-form", method: verb || DEFAULT_METHOD }.merge(attributes)

FormBuilder.new(name, params, Values.new(values), attributes, &blk)
end
end
end
end

0 comments on commit e95a758

Please sign in to comment.