diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index c9e554acff..232e5995c8 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -1,5 +1,13 @@ *SVN* +* Add the following RJS methods: [Sam Stephenson] + + * alert - Displays an alert() dialog + * redirect_to - Changes window.location.href to simulate a browser redirect + * call - Calls a JavaScript function + * assign - Assigns to a JavaScript variable + * << - Inserts an arbitrary JavaScript string + * Fix incorrect documentation for form_for [Nicholas Seckar] * Don't include a layout when rendering an rjs template using render's :template option. [Marcel Molina Jr.] diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb index a0f3a6b42d..89d9ea7f2d 100644 --- a/actionpack/lib/action_view/helpers/prototype_helper.rb +++ b/actionpack/lib/action_view/helpers/prototype_helper.rb @@ -422,8 +422,8 @@ module ActionView # insert_html :bottom, 'list', '
  • Last item
  • ' # def insert_html(position, id, *options_for_render) - html = render(*options_for_render) - record "new Insertion.#{position.to_s.camelize}(#{id.inspect}, #{html.inspect})" + insertion = position.to_s.camelize + call "new Insertion.#{insertion}", id, render(*options_for_render) end # Replaces the inner HTML of the DOM element with the given +id+. @@ -436,25 +436,51 @@ module ActionView # replace_html 'person-45', :partial => 'person', :object => @person # def replace_html(id, *options_for_render) - html = render(*options_for_render) - record "Element.update(#{id.inspect}, #{html.inspect})" + call 'Element.update', id, render(*options_for_render) end # Removes the DOM elements with the given +ids+ from the page. def remove(*ids) - record "#{ids.inspect}.each(Element.remove)" + record "#{javascript_object_for(ids)}.each(Element.remove)" end # Shows hidden DOM elements with the given +ids+. def show(*ids) - record "Element.show(#{ids.map {|id| id.inspect} * ', '})" + call 'Element.show', *ids end # Hides the visible DOM elements with the given +ids+. def hide(*ids) - record "Element.hide(#{ids.map {|id| id.inspect} * ', '})" + call 'Element.hide', *ids end - + + # Displays an alert dialog with the given +message+. + def alert(message) + call 'alert', message + end + + # Redirects the browser to the given +location+, in the same form as + # +url_for+. + def redirect_to(location) + assign 'window.location.href', @context.url_for(location) + end + + # Calls the JavaScript +function+, optionally with the given + # +arguments+. + def call(function, *arguments) + record "#{function}(#{arguments_for_call(arguments)})" + end + + # Assigns the JavaScript +variable+ the given +value+. + def assign(variable, value) + record "#{variable} = #{javascript_object_for(value)}" + end + + # Writes raw JavaScript to the page. + def <<(javascript) + @lines << javascript + end + private def method_missing(method, *arguments, &block) record @context.send(method, *arguments, &block) @@ -462,7 +488,7 @@ module ActionView def record(line) returning line = "#{line.to_s.chomp.gsub /\;$/, ''};" do - @lines << line + self << line end end @@ -471,6 +497,14 @@ module ActionView @context.render(*options_for_render) : options_for_render.first.to_s end + + def javascript_object_for(object) + object.respond_to?(:to_json) ? object.to_json : object.inspect + end + + def arguments_for_call(arguments) + arguments.map { |argument| javascript_object_for(argument) }.join ', ' + end end # Yields a JavaScriptGenerator and returns the generated JavaScript code. diff --git a/actionpack/test/template/prototype_helper_test.rb b/actionpack/test/template/prototype_helper_test.rb index 32292a7e18..56485bc21c 100644 --- a/actionpack/test/template/prototype_helper_test.rb +++ b/actionpack/test/template/prototype_helper_test.rb @@ -192,6 +192,15 @@ class JavaScriptGeneratorTest < Test::Unit::TestCase @generator.hide('foo', 'bar', 'baz') end + def test_alert + assert_equal 'alert("hello");', @generator.alert('hello') + end + + def test_redirect_to + assert_equal 'window.location.href = "http://www.example.com/welcome";', + @generator.redirect_to(:action => 'welcome') + end + def test_to_s @generator.insert_html(:top, 'element', '

    This is a test

    ') @generator.insert_html(:bottom, 'element', '

    This is a test

    ')