New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Form helper #16
Form helper #16
Conversation
1 similar comment
2 similar comments
1 similar comment
# 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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change 'please consider to have a look' to 'please consider having a look'
👍 Looks great. Love the idea of a |
❤️ |
👍 agreed, love the no monkey patching |
👍 I do love the no monkey patching. In my case, I really needed the ability to use HAML within my form (the form fields are inside much larger table). I made my own very quick and dirty helper to get it working for now with HAML. Is it possible that a similar approach to Padrino could eventually be used for form_for? module Client end
module Client::Helpers
module YieldableForm
class Builder < Lotus::Helpers::FormHelper::FormBuilder
CONTENT_TAGS.each do |tag|
class_eval %{
def #{ tag }(content = nil, attributes = nil, &blk)
self.class.html_node.new(:#{ tag }, blk || content, attributes || content, options)
end
}
end
EMPTY_TAGS.each do |tag|
class_eval %{
def #{ tag }(attributes = nil)
Lotus::Helpers::HtmlHelper::EmptyHtmlNode.new(:#{ tag }, attributes)
end
}
end
def with_content(content)
form(content, @attributes)
end
end
def yieldable_form_for(name, url, options = {}, &blk)
init_haml_helpers
values = Lotus::Helpers::FormHelper::Values.new(options.delete(:values), params)
verb = :patch if values.update?
attributes = {
action: url, id: "#{ name }-form",
method: verb || Lotus::Helpers::FormHelper::DEFAULT_METHOD
}.merge(options)
form = Builder.new(name, values, attributes)
form.with_content(Lotus::Utils::Escape::SafeString.new(capture_haml(form, &blk)))
end
end
end |
@danelowe What's that = f = form_for(book)
.input
= f.label :title
= f.text_input :title
= f.close The difference for a dev is minimal: we assign What do you think? |
@jodosha I like your suggestion. I had considered that approach. The only reason I didn't implement it was that I stopped as soon as I got something to at least work, and at the time wasn't certain if or how I could achieve your approach. Thanks! |
I want to avoid this.
That's totally understandable 😸 |
@jodosha overall, it looks 👍 , btw I am wondering if we should support the
|
@joneslee85 The idea here is to be agnostic. We accept a text_field :title, 'data-hello-world': '123' Three motivations behind this choice:
More about the last point. HTML and Form helpers here are primary designed to understand hierarchical document concepts. We have concrete methods to build already known tags (eg. tag(:foo, 'Hi', id: 'bar') # => <foo id="bar">Hi</foo>
empty_tag(:foo, id: 'bar') # => <foo id="bar"> |
@jodosha if so, i am good 👍 with that |
Introduction
By including
FormHelper
it will inject one public method:form_for
.This is a HTML5 form generator.
Technical notes
Zero monkey-patch
This feature has a similar syntax to other Ruby gems with the same purpose, but it has a different usage if compared with Rails or Padrino.
Those frameworks allow a syntax like this:
The code above isn't a valid ERB template. To make it work, Rails uses monkey-patches ERB, and Padrino supports only HAML with that syntax.
One of the pillars of Lotus is "zero monkey-patch of Ruby core and stdlib". We want to keep this principle for this feature too.
Template engine independent
Avoiding monkey-patch has an advantage here. Lotus::Helpers are designed to enhance Lotus::View. This framework supports a lot of template engines, because it's powered by Tilt.
This form generator is designed to be template engine independent.
One output block
The technical compromise for the principles described above is to use the form builder in an unique output block.
This will produce
Method in views
An alternative usage is to define a concrete method in a view and to use it in the template:
Features
PUT
/PATCH
/DELETE
HTTP verbs aren't understood by browsers)id
,name
,value
.value
attributesSupported tags and inputs
color_field
date_field
datetime_field
datetime_local_field
email_field
hidden_field
file_field
fields_for
form_for
label
text_field
password_field
radio_button
select
submit
Examples
Basic usage
Method override
Nested fields
Form for resources
Form to create a new resource
Form to update an existing resource
Share markup between new and update templates
Automatic values
When a form needs to be rendered again because of validation failures, or when a form to update a resource is rendered, the form helper is able to fill the appropriate values.
The params will always take the precedence, then it will lookup for the values passed as first argument to
form_for
.