From 463fc7110755485ee2644690cb87023357f92f9a Mon Sep 17 00:00:00 2001 From: "Erik St. Martin" Date: Sun, 24 Jan 2010 11:57:38 -0500 Subject: making non remote versions of link_to, button_to, submit_tag and image_submit_tag output data attributes for things like :confirm, :method, :popup, and :disable_with --- .../lib/action_view/helpers/form_tag_helper.rb | 20 ++------ .../lib/action_view/helpers/javascript_helper.rb | 41 ++++++++++++++++ actionpack/lib/action_view/helpers/url_helper.rb | 54 +--------------------- actionpack/test/template/form_tag_helper_test.rb | 12 ++--- actionpack/test/template/url_helper_test.rb | 28 +++++------ 5 files changed, 68 insertions(+), 87 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/form_tag_helper.rb b/actionpack/lib/action_view/helpers/form_tag_helper.rb index 048bedc7ba..ebce5c1513 100644 --- a/actionpack/lib/action_view/helpers/form_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/form_tag_helper.rb @@ -352,33 +352,24 @@ module ActionView # # => # # submit_tag "Complete sale", :disable_with => "Please wait..." - # # => # # submit_tag nil, :class => "form_submit" # # => # # submit_tag "Edit", :disable_with => "Editing...", :class => "edit-button" - # # => def submit_tag(value = "Save changes", options = {}) options.stringify_keys! 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); }" - options["onclick"] << "this.setAttribute('originalValue', this.value);this.disabled = true;#{disable_with};" - options["onclick"] << "result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit());" - options["onclick"] << "if (result == false) { this.value = this.getAttribute('originalValue');this.disabled = false; }return result;" + add_disable_with_to_attributes!(options, disable_with) 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 +402,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/javascript_helper.rb b/actionpack/lib/action_view/helpers/javascript_helper.rb index adb35ccfa2..ba6aefca26 100644 --- a/actionpack/lib/action_view/helpers/javascript_helper.rb +++ b/actionpack/lib/action_view/helpers/javascript_helper.rb @@ -188,6 +188,47 @@ module ActionView end protected + def convert_options_to_javascript!(html_options, url = '') + confirm, popup = html_options.delete("confirm"), html_options.delete("popup") + + method, href = html_options.delete("method"), html_options['href'] + + if popup && method + raise ActionView::ActionViewError, "You can't use :popup and :method in the same link" + elsif confirm && popup + add_confirm_to_attributes!(html_options, confirm) + html_options["data-popup"] = popup_attributes(popup) + elsif confirm && method + add_confirm_to_attributes!(html_options, confirm) + add_method_to_attributes!(html_options, method, url) + elsif confirm + add_confirm_to_attributes!(html_options, confirm) + elsif method + add_method_to_attributes!(html_options, method, url) + elsif popup + html_options["data-popup"] = popup_attributes(popup) + end + end + + def add_confirm_to_attributes!(html_options, confirm) + html_options["data-confirm"] = confirm if confirm + end + + def add_method_to_attributes!(html_options, method, url = nil) + html_options["data-method"] = method + if url.size > 0 + html_options["data-url"] = url + end + end + + def add_disable_with_to_attributes!(html_options, disable_with) + html_options["data-disable-with"] = disable_with if disable_with + end + + def popup_attributes(popup) + popup.is_a?(Array) ? "{title: '#{popup.first}', options: '#{popup.last}'}" : "true" + end + def options_for_javascript(options) if options.empty? '{}' diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb index 511386fede..4424dbba42 100644 --- a/actionpack/lib/action_view/helpers/url_helper.rb +++ b/actionpack/lib/action_view/helpers/url_helper.rb @@ -305,12 +305,11 @@ 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.merge!("type" => "submit", "value" => name) @@ -563,55 +562,6 @@ module ActionView end private - def convert_options_to_javascript!(html_options, url = '') - confirm, popup = html_options.delete("confirm"), html_options.delete("popup") - - method, href = html_options.delete("method"), html_options['href'] - - html_options["onclick"] = case - when popup && method - raise ActionView::ActionViewError, "You can't use :popup and :method in the same link" - when confirm && popup - "if (#{confirm_javascript_function(confirm)}) { #{popup_javascript_function(popup)} };return false;" - 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;" - when popup - "#{popup_javascript_function(popup)}return false;" - else - html_options["onclick"] - end - end - - def confirm_javascript_function(confirm) - "confirm('#{escape_javascript(confirm)}')" - end - - def popup_javascript_function(popup) - popup.is_a?(Array) ? "window.open(this.href,'#{popup.first}','#{popup.last}');" : "window.open(this.href);" - 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};" - - 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);" - 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);" - end - submit_function << "f.submit();" - 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 diff --git a/actionpack/test/template/form_tag_helper_test.rb b/actionpack/test/template/form_tag_helper_test.rb index 47462b1237..c8d929cee8 100644 --- a/actionpack/test/template/form_tag_helper_test.rb +++ b/actionpack/test/template/form_tag_helper_test.rb @@ -285,35 +285,35 @@ class FormTagHelperTest < ActionView::TestCase def test_submit_tag assert_dom_equal( - %(), - submit_tag("Save", :disable_with => "Saving...", :onclick => "alert('hello!')") + %(), + submit_tag("Save", :disable_with => "Saving...", :onclick => "alert('hello!');") ) end def test_submit_tag_with_no_onclick_options assert_dom_equal( - %(), + %(), submit_tag("Save", :disable_with => "Saving...") ) end def test_submit_tag_with_confirmation assert_dom_equal( - %(), + %(), submit_tag("Save", :confirm => "Are you sure?") ) end def test_submit_tag_with_confirmation_and_with_disable_with assert_dom_equal( - %(), + %(), submit_tag("Save", :disable_with => "Saving...", :confirm => "Are you sure?") ) end def test_image_submit_tag_with_confirmation assert_dom_equal( - %(), + %(), 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 d4b58efe1e..4298be7a1e 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( - "
", + "
", button_to("Hello", "http://www.example.com", :confirm => "Are you sure?") ) end @@ -170,76 +170,76 @@ class UrlHelperTest < ActionView::TestCase def test_link_tag_with_javascript_confirm assert_dom_equal( - "Hello", + "Hello", link_to("Hello", "http://www.example.com", :confirm => "Are you sure?") ) assert_dom_equal( - "Hello", + "Hello", link_to("Hello", "http://www.example.com", :confirm => "You can't possibly be sure, can you?") ) assert_dom_equal( - "Hello", + "Hello", link_to("Hello", "http://www.example.com", :confirm => "You can't possibly be sure,\n can you?") ) end def test_link_tag_with_popup assert_dom_equal( - "Hello", + "Hello", link_to("Hello", "http://www.example.com", :popup => true) ) assert_dom_equal( - "Hello", + "Hello", link_to("Hello", "http://www.example.com", :popup => 'true') ) assert_dom_equal( - "Hello", + "Hello", link_to("Hello", "http://www.example.com", :popup => ['window_name', 'width=300,height=300']) ) end def test_link_tag_with_popup_and_javascript_confirm assert_dom_equal( - "Hello", + "Hello", link_to("Hello", "http://www.example.com", { :popup => true, :confirm => "Fo' sho'?" }) ) assert_dom_equal( - "Hello", + "Hello", link_to("Hello", "http://www.example.com", { :popup => ['window_name', 'width=300,height=300'], :confirm => "Are you serious?" }) ) end def test_link_tag_using_post_javascript assert_dom_equal( - "Hello", + "Hello", link_to("Hello", "http://www.example.com", :method => :post) ) end def test_link_tag_using_delete_javascript assert_dom_equal( - "Destroy", + "Destroy", link_to("Destroy", "http://www.example.com", :method => :delete) ) end def test_link_tag_using_delete_javascript_and_href assert_dom_equal( - "Destroy", + "Destroy", link_to("Destroy", "http://www.example.com", :method => :delete, :href => '#') ) end def test_link_tag_using_post_javascript_and_confirm assert_dom_equal( - "Hello", + "Hello", 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( - "Destroy", + "Destroy", 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" ) -- cgit v1.2.3