aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack
diff options
context:
space:
mode:
authorErik St. Martin <alakriti@gmail.com>2010-01-30 19:44:35 -0600
committerJoshua Peek <josh@joshpeek.com>2010-01-30 19:44:35 -0600
commit392817cf11e2e840eb564dd4f8713092cff167f8 (patch)
tree242a19782af6c4e67fd50f324c5781ecde93d4a4 /actionpack
parent7d9ed8eec1c899dac10d582ced07149fe5c58c4f (diff)
downloadrails-392817cf11e2e840eb564dd4f8713092cff167f8.tar.gz
rails-392817cf11e2e840eb564dd4f8713092cff167f8.tar.bz2
rails-392817cf11e2e840eb564dd4f8713092cff167f8.zip
updating link_to and button_to to support :remote => true and other options such as :confirm in a unobtrusive manor
Signed-off-by: Joshua Peek <josh@joshpeek.com>
Diffstat (limited to 'actionpack')
-rw-r--r--actionpack/lib/action_view/helpers/form_tag_helper.rb12
-rw-r--r--actionpack/lib/action_view/helpers/url_helper.rb77
-rw-r--r--actionpack/test/template/form_tag_helper_test.rb6
-rw-r--r--actionpack/test/template/url_helper_test.rb25
4 files changed, 70 insertions, 50 deletions
diff --git a/actionpack/lib/action_view/helpers/form_tag_helper.rb b/actionpack/lib/action_view/helpers/form_tag_helper.rb
index 048bedc7ba..0e034d781a 100644
--- a/actionpack/lib/action_view/helpers/form_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_tag_helper.rb
@@ -57,7 +57,7 @@ module ActionView
# ==== Examples
# select_tag "people", options_from_collection_for_select(@people, "name", "id")
# # <select id="people" name="people"><option value="1">David</option></select>
- #
+ #
# select_tag "people", "<option>David</option>"
# # => <select id="people" name="people"><option>David</option></select>
#
@@ -128,7 +128,7 @@ module ActionView
# Creates a label field
#
- # ==== Options
+ # ==== Options
# * Creates standard HTML attributes for the tag.
#
# ==== Examples
@@ -367,7 +367,7 @@ module ActionView
if disable_with = options.delete("disable_with")
disable_with = "this.value='#{disable_with}'"
disable_with << ";#{options.delete('onclick')}" if options['onclick']
-
+
options["onclick"] = "if (window.hiddenCommit) { window.hiddenCommit.setAttribute('value', this.value); }"
options["onclick"] << "else { hiddenCommit = document.createElement('input');hiddenCommit.type = 'hidden';"
options["onclick"] << "hiddenCommit.value = this.value;hiddenCommit.name = this.name;this.form.appendChild(hiddenCommit); }"
@@ -377,8 +377,7 @@ module ActionView
end
if confirm = options.delete("confirm")
- options["onclick"] ||= 'return true;'
- options["onclick"] = "if (!#{confirm_javascript_function(confirm)}) return false; #{options['onclick']}"
+ add_confirm_to_attributes!(options, confirm)
end
tag :input, { "type" => "submit", "name" => "commit", "value" => value }.update(options.stringify_keys)
@@ -411,8 +410,7 @@ module ActionView
options.stringify_keys!
if confirm = options.delete("confirm")
- options["onclick"] ||= ''
- options["onclick"] += "return #{confirm_javascript_function(confirm)};"
+ add_confirm_to_attributes!(options, confirm)
end
tag :input, { "type" => "image", "src" => path_to_image(source) }.update(options.stringify_keys)
diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb
index d6bfc6d4c9..9e52275537 100644
--- a/actionpack/lib/action_view/helpers/url_helper.rb
+++ b/actionpack/lib/action_view/helpers/url_helper.rb
@@ -218,11 +218,11 @@ module ActionView
html_options = args[2]
url = url_for(options)
+ html_options = convert_options_to_data_attributes(options, html_options)
if html_options
html_options = html_options.stringify_keys
href = html_options['href']
- convert_options_to_javascript!(html_options, url)
tag_options = tag_options(html_options)
else
tag_options = nil
@@ -291,14 +291,10 @@ module ActionView
request_token_tag = tag(:input, :type => "hidden", :name => request_forgery_protection_token.to_s, :value => form_authenticity_token)
end
- if confirm = html_options.delete("confirm")
- html_options["onclick"] = "return #{confirm_javascript_function(confirm)};"
- end
-
url = options.is_a?(String) ? options : self.url_for(options)
name ||= url
- convert_options_to_javascript!(html_options, url)
+ html_options = convert_options_to_data_attributes(options, html_options)
html_options.merge!("type" => "submit", "value" => name)
@@ -551,46 +547,65 @@ module ActionView
end
private
- def convert_options_to_javascript!(html_options, url = '')
+ def convert_options_to_data_attributes(options, html_options)
+ html_options = {} if html_options.nil?
+ html_options = html_options.stringify_keys
+
+ if (options.is_a?(Hash) && options.key?('remote')) || (html_options.is_a?(Hash) && html_options.key?('remote'))
+ html_options['data-remote'] = 'true'
+ options.delete('remote') if options.is_a?(Hash)
+ html_options.delete('remote') if html_options.is_a?(Hash)
+ end
+
confirm = html_options.delete("confirm")
- method, href = html_options.delete("method"), html_options['href']
if html_options.key?("popup")
ActiveSupport::Deprecation.warn(":popup has been deprecated", caller)
end
- html_options["onclick"] = case
- when confirm && method
- "if (#{confirm_javascript_function(confirm)}) { #{method_javascript_function(method, url, href)} };return false;"
- when confirm
- "return #{confirm_javascript_function(confirm)};"
- when method
- "#{method_javascript_function(method, url, href)}return false;"
- else
- html_options["onclick"]
+ method, href = html_options.delete("method"), html_options['href']
+
+ if confirm && method
+ add_confirm_to_attributes!(html_options, confirm)
+ add_method_to_attributes!(html_options, method)
+ elsif confirm
+ add_confirm_to_attributes!(html_options, confirm)
+ elsif method
+ add_method_to_attributes!(html_options, method)
end
+
+ html_options["data-url"] = options[:url] if options.is_a?(Hash) && options[:url]
+
+ html_options
end
- def confirm_javascript_function(confirm)
- "confirm('#{escape_javascript(confirm)}')"
+ def add_confirm_to_attributes!(html_options, confirm)
+ html_options["data-confirm"] = confirm if confirm
end
- def method_javascript_function(method, url = '', href = nil)
- action = (href && url.size > 0) ? "'#{url}'" : 'this.href'
- submit_function =
- "var f = document.createElement('form'); f.style.display = 'none'; " +
- "this.parentNode.appendChild(f); f.method = 'POST'; f.action = #{action};"
+ def add_method_to_attributes!(html_options, method)
+ html_options["rel"] = "nofollow" if method && method.to_s.downcase == "delete"
+ html_options["data-method"] = method if method
+ end
- unless method == :post
- submit_function << "var m = document.createElement('input'); m.setAttribute('type', 'hidden'); "
- submit_function << "m.setAttribute('name', '_method'); m.setAttribute('value', '#{method}'); f.appendChild(m);"
+ def add_disable_with_to_attributes!(html_options, disable_with)
+ html_options["data-disable-with"] = disable_with if disable_with
+ end
+
+ def options_for_javascript(options)
+ if options.empty?
+ '{}'
+ else
+ "{#{options.keys.map { |k| "#{k}:#{options[k]}" }.sort.join(', ')}}"
end
+ end
- if protect_against_forgery?
- submit_function << "var s = document.createElement('input'); s.setAttribute('type', 'hidden'); "
- submit_function << "s.setAttribute('name', '#{request_forgery_protection_token}'); s.setAttribute('value', '#{escape_javascript form_authenticity_token}'); f.appendChild(s);"
+ def array_or_string_for_javascript(option)
+ if option.kind_of?(Array)
+ "['#{option.join('\',\'')}']"
+ elsif !option.nil?
+ "'#{option}'"
end
- submit_function << "f.submit();"
end
# Processes the +html_options+ hash, converting the boolean
diff --git a/actionpack/test/template/form_tag_helper_test.rb b/actionpack/test/template/form_tag_helper_test.rb
index 47462b1237..41ab5c1621 100644
--- a/actionpack/test/template/form_tag_helper_test.rb
+++ b/actionpack/test/template/form_tag_helper_test.rb
@@ -299,21 +299,21 @@ class FormTagHelperTest < ActionView::TestCase
def test_submit_tag_with_confirmation
assert_dom_equal(
- %(<input name='commit' type='submit' value='Save' onclick="if (!confirm('Are you sure?')) return false; return true;"/>),
+ %(<input name='commit' type='submit' value='Save' data-confirm="Are you sure?" />),
submit_tag("Save", :confirm => "Are you sure?")
)
end
def test_submit_tag_with_confirmation_and_with_disable_with
assert_dom_equal(
- %(<input name="commit" onclick="if (!confirm('Are you sure?')) return false; if (window.hiddenCommit) { window.hiddenCommit.setAttribute('value', this.value); }else { hiddenCommit = document.createElement('input');hiddenCommit.type = 'hidden';hiddenCommit.value = this.value;hiddenCommit.name = this.name;this.form.appendChild(hiddenCommit); }this.setAttribute('originalValue', this.value);this.disabled = true;this.value='Saving...';result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit());if (result == false) { this.value = this.getAttribute('originalValue');this.disabled = false; }return result;" type="submit" value="Save" />),
+ %(<input name="commit" onclick="if (window.hiddenCommit) { window.hiddenCommit.setAttribute('value', this.value); }else { hiddenCommit = document.createElement('input');hiddenCommit.type = 'hidden';hiddenCommit.value = this.value;hiddenCommit.name = this.name;this.form.appendChild(hiddenCommit); }this.setAttribute('originalValue', this.value);this.disabled = true;this.value='Saving...';result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit());if (result == false) { this.value = this.getAttribute('originalValue');this.disabled = false; }return result;" data-confirm="Are you sure?" type="submit" value="Save" />),
submit_tag("Save", :disable_with => "Saving...", :confirm => "Are you sure?")
)
end
def test_image_submit_tag_with_confirmation
assert_dom_equal(
- %(<input type="image" src="/images/save.gif" onclick="return confirm('Are you sure?');"/>),
+ %(<input type="image" src="/images/save.gif" data-confirm="Are you sure?" />),
image_submit_tag("save.gif", :confirm => "Are you sure?")
)
end
diff --git a/actionpack/test/template/url_helper_test.rb b/actionpack/test/template/url_helper_test.rb
index dd28aec786..6d9384d40b 100644
--- a/actionpack/test/template/url_helper_test.rb
+++ b/actionpack/test/template/url_helper_test.rb
@@ -76,7 +76,7 @@ class UrlHelperTest < ActionView::TestCase
def test_button_to_with_javascript_confirm
assert_dom_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>",
+ "<form method=\"post\" action=\"http://www.example.com\" class=\"button-to\"><div><input data-confirm=\"Are you sure?\" type=\"submit\" value=\"Hello\" /></div></form>",
button_to("Hello", "http://www.example.com", :confirm => "Are you sure?")
)
end
@@ -170,50 +170,57 @@ class UrlHelperTest < ActionView::TestCase
def test_link_tag_with_javascript_confirm
assert_dom_equal(
- "<a href=\"http://www.example.com\" onclick=\"return confirm('Are you sure?');\">Hello</a>",
+ "<a href=\"http://www.example.com\" data-confirm=\"Are you sure?\">Hello</a>",
link_to("Hello", "http://www.example.com", :confirm => "Are you sure?")
)
assert_dom_equal(
- "<a href=\"http://www.example.com\" onclick=\"return confirm('You can\\'t possibly be sure, can you?');\">Hello</a>",
+ "<a href=\"http://www.example.com\" data-confirm=\"You can't possibly be sure, can you?\">Hello</a>",
link_to("Hello", "http://www.example.com", :confirm => "You can't possibly be sure, can you?")
)
assert_dom_equal(
- "<a href=\"http://www.example.com\" onclick=\"return confirm('You can\\'t possibly be sure,\\n can you?');\">Hello</a>",
+ "<a href=\"http://www.example.com\" data-confirm=\"You can't possibly be sure,\n can you?\">Hello</a>",
link_to("Hello", "http://www.example.com", :confirm => "You can't possibly be sure,\n can you?")
)
end
+ def test_link_to_with_remote
+ assert_dom_equal(
+ "<a href=\"http://www.example.com\" data-remote=\"true\">Hello</a>",
+ link_to("Hello", "http://www.example.com", :remote => true)
+ )
+ end
+
def test_link_tag_using_post_javascript
assert_dom_equal(
- "<a href='http://www.example.com' onclick=\"var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href;f.submit();return false;\">Hello</a>",
+ "<a href='http://www.example.com' data-method=\"post\">Hello</a>",
link_to("Hello", "http://www.example.com", :method => :post)
)
end
def test_link_tag_using_delete_javascript
assert_dom_equal(
- "<a href='http://www.example.com' onclick=\"var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href;var m = document.createElement('input'); m.setAttribute('type', 'hidden'); m.setAttribute('name', '_method'); m.setAttribute('value', 'delete'); f.appendChild(m);f.submit();return false;\">Destroy</a>",
+ "<a href='http://www.example.com' rel=\"nofollow\" data-method=\"delete\">Destroy</a>",
link_to("Destroy", "http://www.example.com", :method => :delete)
)
end
def test_link_tag_using_delete_javascript_and_href
assert_dom_equal(
- "<a href='\#' onclick=\"var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = 'http://www.example.com';var m = document.createElement('input'); m.setAttribute('type', 'hidden'); m.setAttribute('name', '_method'); m.setAttribute('value', 'delete'); f.appendChild(m);f.submit();return false;\">Destroy</a>",
+ "<a href='\#' rel=\"nofollow\" data-method=\"delete\">Destroy</a>",
link_to("Destroy", "http://www.example.com", :method => :delete, :href => '#')
)
end
def test_link_tag_using_post_javascript_and_confirm
assert_dom_equal(
- "<a href=\"http://www.example.com\" onclick=\"if (confirm('Are you serious?')) { var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = this.href;f.submit(); };return false;\">Hello</a>",
+ "<a href=\"http://www.example.com\" data-method=\"post\" data-confirm=\"Are you serious?\">Hello</a>",
link_to("Hello", "http://www.example.com", :method => :post, :confirm => "Are you serious?")
)
end
def test_link_tag_using_delete_javascript_and_href_and_confirm
assert_dom_equal(
- "<a href='\#' onclick=\"if (confirm('Are you serious?')) { var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'POST'; f.action = 'http://www.example.com';var m = document.createElement('input'); m.setAttribute('type', 'hidden'); m.setAttribute('name', '_method'); m.setAttribute('value', 'delete'); f.appendChild(m);f.submit(); };return false;\">Destroy</a>",
+ "<a href='\#' rel=\"nofollow\" data-confirm=\"Are you serious?\" data-method=\"delete\">Destroy</a>",
link_to("Destroy", "http://www.example.com", :method => :delete, :href => '#', :confirm => "Are you serious?"),
"When specifying url, form should be generated with it, but not this.href"
)