From 8dc4f4623354b65a639ac3c8981e1c362801d722 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sun, 12 Feb 2006 20:10:59 +0000 Subject: Also support replace and replace_html and some refactoring in JavaScriptElementProxy [DHH] git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@3588 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- .../action_view/helpers/javascripts/prototype.js | 47 +++++++++++----------- .../lib/action_view/helpers/prototype_helper.rb | 34 ++++++++++++---- actionpack/test/template/prototype_helper_test.rb | 5 +++ 3 files changed, 55 insertions(+), 31 deletions(-) diff --git a/actionpack/lib/action_view/helpers/javascripts/prototype.js b/actionpack/lib/action_view/helpers/javascripts/prototype.js index f37149127f..62ee54efc1 100644 --- a/actionpack/lib/action_view/helpers/javascripts/prototype.js +++ b/actionpack/lib/action_view/helpers/javascripts/prototype.js @@ -436,7 +436,8 @@ var Enumerable = { var collections = [this].concat(args).map($A); return this.map(function(value, index) { - return iterator(collections.pluck(index)); + iterator(value = collections.pluck(index)); + return value; }); }, @@ -942,19 +943,6 @@ Object.extend(Element, { setTimeout(function() {html.evalScripts()}, 10); }, - replace: function(element, html) { - element = $(element); - if (element.outerHTML) { - element.outerHTML = html.stripScripts(); - } else { - var range = element.ownerDocument.createRange(); - range.selectNodeContents(element); - element.parentNode.replaceChild( - range.createContextualFragment(html.stripScripts()), element); - } - setTimeout(function() {html.evalScripts()}, 10); - }, - getHeight: function(element) { element = $(element); return element.offsetHeight; @@ -1317,8 +1305,18 @@ var Field = { $(arguments[i]).value = ''; }, - focus: function(element) { - $(element).focus(); + // Pass the field id or element as the first parameter and optionally a triggering delay in micro-seconds as the second. + // The delay is useful when the focus is part of effects that won't finish instantly since they prevent the focus from + // taking hold. Set the delay to right after the effect finishes and the focus will work. + focus: function() { + element = $(arguments[0]); + delay = arguments[1]; + + if (delay) { + setTimeout(function() { $(element).focus(); }, delay) + } else { + $(element).focus(); + } }, present: function() { @@ -1551,15 +1549,16 @@ Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { Abstract.EventObserver = function() {} Abstract.EventObserver.prototype = { - initialize: function(element, callback) { - this.element = $(element); - this.callback = callback; + initialize: function() { + this.element = $(arguments[0]); + this.callback = arguments[1]; + this.trigger = arguments[2]; this.lastValue = this.getValue(); if (this.element.tagName.toLowerCase() == 'form') this.registerFormCallbacks(); else - this.registerCallback(this.element); + this.registerCallback(this.element, this.trigger); }, onElementEvent: function() { @@ -1573,11 +1572,13 @@ Abstract.EventObserver.prototype = { registerFormCallbacks: function() { var elements = Form.getElements(this.element); for (var i = 0; i < elements.length; i++) - this.registerCallback(elements[i]); + this.registerCallback(elements[i], this.trigger); }, - registerCallback: function(element) { - if (element.type) { + registerCallback: function(element, trigger) { + if (trigger && element.type) { + Event.observe(element, trigger, this.onElementEvent.bind(this)); + } else if (element.type) { switch (element.type.toLowerCase()) { case 'checkbox': case 'radio': diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb index f0d2b405d2..ae68e21624 100644 --- a/actionpack/lib/action_view/helpers/prototype_helper.rb +++ b/actionpack/lib/action_view/helpers/prototype_helper.rb @@ -501,9 +501,9 @@ module ActionView # page.insert_html :bottom, :partial => 'person', :object => @person # # # Replace an existing person - # page.replace_element 'person_45', :partial => 'person', :object => @person + # page.replace 'person_45', :partial => 'person', :object => @person # - def replace_element(id, *options_for_render) + def replace(id, *options_for_render) call 'Element.replace', id, render(*options_for_render) end @@ -672,16 +672,34 @@ module ActionView @generator << root end - private - def method_missing(method, *arguments) - method_chain = @generator.instance_variable_get("@lines") + def assign(variable, value) + append_to_function_chain! "#{variable} = #{@generator.send(:javascript_object_for, value)}" + end - last_method = method_chain[-1] - method_chain[-1] = last_method[0..-2] if last_method[-1..-1] == ";" # strip trailing ; from last method call - method_chain[-1] += ".#{method}(#{@generator.send(:arguments_for_call, arguments)});" + def replace_html(*options_for_render) + call 'update', @generator.render(*options_for_render) + end + def replace(*options_for_render) + call 'replace', @generator.render(*options_for_render) + end + + private + def call(function, *arguments) + append_to_function_chain!("#{function}(#{@generator.send(:arguments_for_call, arguments)})") self end + + alias_method :method_missing, :call + + def function_chain + @function_chain ||= @generator.instance_variable_get("@lines") + end + + def append_to_function_chain!(call) + function_chain[-1] = function_chain[-1][0..-2] if function_chain[-1][-1..-1] == ";" # strip last ; + function_chain[-1] += ".#{call};" + end end end end diff --git a/actionpack/test/template/prototype_helper_test.rb b/actionpack/test/template/prototype_helper_test.rb index 8657b1f107..6ce8380a69 100644 --- a/actionpack/test/template/prototype_helper_test.rb +++ b/actionpack/test/template/prototype_helper_test.rb @@ -237,6 +237,11 @@ Element.update("baz", "

This is a test

"); assert_equal %($('hello').hide();), @generator.to_s end + def test_element_proxy_assignment + @generator['hello'].assign :width, 400 + assert_equal %($('hello').width = 400;), @generator.to_s + end + def test_element_proxy_two_deep @generator['hello'].hide("first").display assert_equal %($('hello').hide("first").display();), @generator.to_s -- cgit v1.2.3