mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Added button_to as a form-based solution to deal with harmful actions that should be hidden behind POSTs. This makes it just as easy as link_to to create a safe trigger for actions like destroy, although it's limited by being a block element, the fixed look, and a no-no inside other forms. #1371 [tom@moertel.com]
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@1437 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
parent
70757cb273
commit
43c470fae4
3 changed files with 116 additions and 1 deletions
|
@ -1,5 +1,7 @@
|
|||
*SVN*
|
||||
|
||||
* Added button_to as a form-based solution to deal with harmful actions that should be hidden behind POSTs. This makes it just as easy as link_to to create a safe trigger for actions like destroy, although it's limited by being a block element, the fixed look, and a no-no inside other forms. #1371 [tom@moertel.com]
|
||||
|
||||
* Fixed image_tag so an exception is not thrown just because the image is missing and alt value can't be generated #1395 [Marcel]
|
||||
|
||||
* Added a third parameter to TextHelper#auto_link called href_options for specifying additional tag options on the links generated #1401 [tyler.kovacs@gmail.com]. Example: auto_link(text, :all, { :target => "_blank" }) to have all the generated links open in a new window.
|
||||
|
|
|
@ -33,6 +33,67 @@ module ActionView
|
|||
end
|
||||
end
|
||||
|
||||
# Generates a form containing a sole button that submits to the
|
||||
# URL given by _options_. Use this method instead of +link_to+
|
||||
# for actions that do not have the safe HTTP GET semantics
|
||||
# implied by using a hypertext link.
|
||||
#
|
||||
# The parameters are the same as for +link_to+. Any _html_options_
|
||||
# that you pass will be applied to the inner +input+ element.
|
||||
# In particular, pass
|
||||
#
|
||||
# :disabled => true/false
|
||||
#
|
||||
# as part of _html_options_ to control whether the button is
|
||||
# disabled. The generated form element is given the class
|
||||
# 'button-to', to which you can attach CSS styles for display
|
||||
# purposes.
|
||||
#
|
||||
# Example 1:
|
||||
#
|
||||
# # inside of controller for "feeds"
|
||||
# button_to "Edit", :action => 'edit', :id => 3
|
||||
#
|
||||
# Generates the following HTML (sans formatting):
|
||||
#
|
||||
# <form method="post" action="/feeds/edit/3" class="button-to">
|
||||
# <div><input value="Edit" type="submit" /></div>
|
||||
# </form>
|
||||
#
|
||||
# Example 2:
|
||||
#
|
||||
# button_to "Destroy", { :action => 'destroy', :id => 3 },
|
||||
# :confirm => "Are you sure?"
|
||||
#
|
||||
# Generates the following HTML (sans formatting):
|
||||
#
|
||||
# <form method="post" action="/feeds/destroy/3" class="button-to">
|
||||
# <div><input onclick="return confirm('Are you sure?');"
|
||||
# value="Destroy" type="submit" />
|
||||
# </div>
|
||||
# </form>
|
||||
#
|
||||
# *NOTE*: This method generates HTML code that represents a form.
|
||||
# Forms are "block" content, which means that you should not try to
|
||||
# insert them into your HTML where only inline content is expected.
|
||||
# For example, you can legally insert a form inside of a +div+ or
|
||||
# +td+ element or in between +p+ elements, but not in the middle of
|
||||
# a run of text, nor can you place a form within another form.
|
||||
# (Bottom line: Always validate your HTML before going public.)
|
||||
|
||||
def button_to(name, options = {}, html_options = nil)
|
||||
html_options = (html_options || {}).stringify_keys
|
||||
convert_boolean_attributes!(html_options, %w( disabled ))
|
||||
convert_confirm_option_to_javascript!(html_options)
|
||||
url, name = options.is_a?(String) ?
|
||||
[ options, name || options ] :
|
||||
[ url_for(options), name || url_for(options) ]
|
||||
html_options.merge!("type" => "submit", "value" => name)
|
||||
"<form method=\"post\" action=\"#{h url}\" class=\"button-to\"><div>" +
|
||||
tag("input", html_options) + "</div></form>"
|
||||
end
|
||||
|
||||
|
||||
# This tag is deprecated. Combine the link_to and AssetTagHelper::image_tag yourself instead, like:
|
||||
# link_to(image_tag("rss", :size => "30x45", :border => 0), "http://www.example.com")
|
||||
def link_image_to(src, options = {}, html_options = {}, *parameters_for_method_reference)
|
||||
|
@ -157,6 +218,36 @@ module ActionView
|
|||
html_options["onclick"] = "return confirm('#{confirm.gsub(/'/, '\\\\\'')}');"
|
||||
end
|
||||
end
|
||||
|
||||
# Processes the _html_options_ hash, converting the boolean
|
||||
# attributes from true/false form into the form required by
|
||||
# HTML/XHTML. (An attribute is considered to be boolean if
|
||||
# its name is listed in the given _bool_attrs_ array.)
|
||||
#
|
||||
# More specifically, for each boolean attribute in _html_options_
|
||||
# given as:
|
||||
#
|
||||
# "attr" => bool_value
|
||||
#
|
||||
# if the the associated _bool_value_ evaluates to true, it is
|
||||
# replaced with the attribute's name; otherwise the attribute is
|
||||
# removed from the _html_options_ hash. (See the XHTML 1.0 spec,
|
||||
# section 4.5 "Attribute Minimization" for more:
|
||||
# http://www.w3.org/TR/xhtml1/#h-4.5)
|
||||
#
|
||||
# Returns the updated _html_options_ hash, which is also modified
|
||||
# in place.
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# convert_boolean_attributes!( html_options,
|
||||
# %w( checked disabled readonly ) )
|
||||
|
||||
def convert_boolean_attributes!(html_options, bool_attrs)
|
||||
bool_attrs.each { |x| html_options[x] = x if html_options.delete(x) }
|
||||
html_options
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -21,6 +21,28 @@ class UrlHelperTest < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
# todo: missing test cases
|
||||
def test_button_to_with_straight_url
|
||||
assert_equal "<form method=\"post\" action=\"http://www.example.com\" class=\"button-to\"><div><input type=\"submit\" value=\"Hello\" /></div></form>", button_to("Hello", "http://www.example.com")
|
||||
end
|
||||
|
||||
def test_button_to_with_javascript_confirm
|
||||
assert_equal(
|
||||
"<form method=\"post\" action=\"http://www.example.com\" class=\"button-to\"><div><input onclick=\"return confirm('Are you sure?');\" type=\"submit\" value=\"Hello\" /></div></form>",
|
||||
button_to("Hello", "http://www.example.com", :confirm => "Are you sure?")
|
||||
)
|
||||
end
|
||||
|
||||
def test_button_to_enabled_disabled
|
||||
assert_equal(
|
||||
"<form method=\"post\" action=\"http://www.example.com\" class=\"button-to\"><div><input type=\"submit\" value=\"Hello\" /></div></form>",
|
||||
button_to("Hello", "http://www.example.com", :disabled => false)
|
||||
)
|
||||
assert_equal(
|
||||
"<form method=\"post\" action=\"http://www.example.com\" class=\"button-to\"><div><input disabled=\"disabled\" type=\"submit\" value=\"Hello\" /></div></form>",
|
||||
button_to("Hello", "http://www.example.com", :disabled => true)
|
||||
)
|
||||
end
|
||||
|
||||
def test_link_tag_with_straight_url
|
||||
assert_equal "<a href=\"http://www.example.com\">Hello</a>", link_to("Hello", "http://www.example.com")
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue