From 96536bebaefccabcbfb5ce9e689dd40c4fb4e294 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sat, 24 Dec 2005 00:52:14 +0000 Subject: [PATCH] Added :select option for JavaScriptMacroHelper#auto_complete_field that makes it easier to only use part of the auto-complete suggestion as the value for insertion [Thomas Fuchs] git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@3344 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- actionpack/CHANGELOG | 8 +++++ .../helpers/java_script_macros_helper.rb | 7 ++++- .../helpers/javascripts/controls.js | 9 ++++-- .../helpers/javascripts/effects.js | 30 +++++++++---------- .../helpers/scriptaculous_helper.rb | 17 +++++++++++ .../template/scriptaculous_helper_test.rb | 9 ++++++ 6 files changed, 61 insertions(+), 19 deletions(-) diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index 93c86e09ab..f2d0b213ce 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -1,5 +1,13 @@ *SVN* +* Added :select option for JavaScriptMacroHelper#auto_complete_field that makes it easier to only use part of the auto-complete suggestion as the value for insertion [Thomas Fuchs] + +* Added delayed execution of Javascript from within RJS #3264 [devslashnull@gmail.com]. Example: + + page.delay(20) do + page.visual_effect :fade, 'notice' + end + * Add session ID to default logging, but remove the verbose description of every step [DHH] * Add the following RJS methods: [Sam Stephenson] diff --git a/actionpack/lib/action_view/helpers/java_script_macros_helper.rb b/actionpack/lib/action_view/helpers/java_script_macros_helper.rb index f0fc092572..a01f91d8f1 100644 --- a/actionpack/lib/action_view/helpers/java_script_macros_helper.rb +++ b/actionpack/lib/action_view/helpers/java_script_macros_helper.rb @@ -105,6 +105,9 @@ def in_place_editor_field(object, method, tag_options = {}, in_place_editor_opti # innerHTML is replaced. # :on_show:: Like on_hide, only now the expression is called # then the div is shown. + # :select:: Pick the class of the element from which the value for + # insertion should be extracted. If this is not specified, + # the entire element is used. def auto_complete_field(field_id, options = {}) function = "new Ajax.Autocompleter(" function << "'#{field_id}', " @@ -115,9 +118,11 @@ def auto_complete_field(field_id, options = {}) js_options[:tokens] = array_or_string_for_javascript(options[:tokens]) if options[:tokens] js_options[:callback] = "function(element, value) { return #{options[:with]} }" if options[:with] js_options[:indicator] = "'#{options[:indicator]}'" if options[:indicator] - {:on_show => :onShow, :on_hide => :onHide, :min_chars => :min_chars}.each do |k,v| + + { :on_show => :onShow, :on_hide => :onHide, :min_chars => :min_chars, :select => :select }.each do |k,v| js_options[v] = options[k] if options[k] end + function << (', ' + options_for_javascript(js_options) + ')') javascript_tag(function) diff --git a/actionpack/lib/action_view/helpers/javascripts/controls.js b/actionpack/lib/action_view/helpers/javascripts/controls.js index 9742b69188..f13733d5f0 100644 --- a/actionpack/lib/action_view/helpers/javascripts/controls.js +++ b/actionpack/lib/action_view/helpers/javascripts/controls.js @@ -221,8 +221,13 @@ Autocompleter.Base.prototype = { this.options.updateElement(selectedElement); return; } - - var value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal'); + var value = ''; + if (this.options.select) { + var nodes = document.getElementsByClassName(this.options.select, selectedElement) || []; + if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select); + } else + value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal'); + var lastTokenPos = this.findLastToken(); if (lastTokenPos != -1) { var newValue = this.element.value.substr(0, lastTokenPos + 1); diff --git a/actionpack/lib/action_view/helpers/javascripts/effects.js b/actionpack/lib/action_view/helpers/javascripts/effects.js index 414398ce47..ebca0c490a 100644 --- a/actionpack/lib/action_view/helpers/javascripts/effects.js +++ b/actionpack/lib/action_view/helpers/javascripts/effects.js @@ -22,23 +22,21 @@ String.prototype.parseColor = function() { } } return(color.length==7 ? color : (arguments[0] || this)); -} +} -Element.collectTextNodesIgnoreClass = function(element, ignoreclass) { - var children = $(element).childNodes; - var text = ''; - var classtest = new RegExp('^([^ ]+ )*' + ignoreclass+ '( [^ ]+)*$','i'); - - for (var i = 0; i < children.length; i++) { - if(children[i].nodeType==3) { - text+=children[i].nodeValue; - } else { - if((!children[i].className.match(classtest)) && children[i].hasChildNodes()) - text += Element.collectTextNodesIgnoreClass(children[i], ignoreclass); - } - } - - return text; +Element.collectTextNodes = function(element) { + return $A($(element).childNodes).collect( function(node) { + return (node.nodeType==3 ? node.nodeValue : + (node.hasChildNodes() ? Element.collectTextNodes(node) : '')); + }).flatten().join(''); +} + +Element.collectTextNodesIgnoreClass = function(element, className) { + return $A($(element).childNodes).collect( function(node) { + return (node.nodeType==3 ? node.nodeValue : + ((node.hasChildNodes() && !Element.hasClassName(node,className)) ? + Element.collectTextNodes(node) : '')); + }).flatten().join(''); } Element.setStyle = function(element, style) { diff --git a/actionpack/lib/action_view/helpers/scriptaculous_helper.rb b/actionpack/lib/action_view/helpers/scriptaculous_helper.rb index 105d89d337..fac628caef 100644 --- a/actionpack/lib/action_view/helpers/scriptaculous_helper.rb +++ b/actionpack/lib/action_view/helpers/scriptaculous_helper.rb @@ -38,6 +38,23 @@ def visual_effect(name, element_id = false, js_options = {}) js_options[:queue] = "'#{js_options[:queue]}'" if js_options[:queue] "new Effect.#{name.to_s.camelize}(#{element},#{options_for_javascript(js_options)});" end + + # Needs more work so + isn't required for concation of effects. Currently, you have to do: + # + # page.parallel_effects do + # page.visual_effect(:highlight, 'dom_id') + + # page.visual_effect(:fade, 'dom_id') + # end + # + # ...naturally, it would be better just to do + # + # page.parallel_effects do + # page.visual_effect :highlight, 'dom_id' + # page.visual_effect :fade, 'dom_id' + # end + def parallel_effects(js_options = {}) #:nodoc: + "new Effect.Parallel([" + yield + "], #{options_for_javascript(js_options)})" + end # Makes the element with the DOM ID specified by +element_id+ sortable # by drag-and-drop and make an Ajax call whenever the sort order has diff --git a/actionpack/test/template/scriptaculous_helper_test.rb b/actionpack/test/template/scriptaculous_helper_test.rb index fb8f745c7d..c185419c72 100644 --- a/actionpack/test/template/scriptaculous_helper_test.rb +++ b/actionpack/test/template/scriptaculous_helper_test.rb @@ -29,6 +29,15 @@ def test_effect assert_equal "new Effect.Shake(element,{});", visual_effect(:shake) assert_equal "new Effect.DropOut('dropme',{queue:'end'});", visual_effect(:drop_out, 'dropme', :queue => :end) end + + def test_parallel_effects + actual = parallel_effects(:duration => 2) do + visual_effect(:highlight, "posts") + + visual_effect(:fade, "fademe", :duration => 4.0) + end + + assert_equal "new Effect.Parallel([new Effect.Highlight('posts',{});new Effect.Fade('fademe',{duration:4.0});], {duration:2})", actual + end def test_sortable_element assert_dom_equal %(), -- GitLab