aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack
diff options
context:
space:
mode:
authorDavid Heinemeier Hansson <david@loudthinking.com>2005-06-26 14:23:36 +0000
committerDavid Heinemeier Hansson <david@loudthinking.com>2005-06-26 14:23:36 +0000
commit521d5fdc72f776e255454a4229bfd1a110da8bc3 (patch)
treef0dca0066f2df22a8edbf285cbbd6109eecc64c9 /actionpack
parentf0608c9165e00466de5a57eb89da9077a8e0c15c (diff)
downloadrails-521d5fdc72f776e255454a4229bfd1a110da8bc3.tar.gz
rails-521d5fdc72f776e255454a4229bfd1a110da8bc3.tar.bz2
rails-521d5fdc72f776e255454a4229bfd1a110da8bc3.zip
Added auto_complete_for to controller and text_field_with_auto_complete to view to make it really, really easy to do Google Suggest style interfaces
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@1525 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'actionpack')
-rwxr-xr-xactionpack/lib/action_controller.rb2
-rw-r--r--actionpack/lib/action_view/helpers/javascript_helper.rb71
2 files changed, 57 insertions, 16 deletions
diff --git a/actionpack/lib/action_controller.rb b/actionpack/lib/action_controller.rb
index 70722a0e73..deead18b5a 100755
--- a/actionpack/lib/action_controller.rb
+++ b/actionpack/lib/action_controller.rb
@@ -49,6 +49,7 @@ require 'action_controller/caching'
require 'action_controller/components'
require 'action_controller/verification'
require 'action_controller/streaming'
+require 'action_controller/auto_complete'
require 'action_view'
ActionController::Base.template_class = ActionView::Base
@@ -69,4 +70,5 @@ ActionController::Base.class_eval do
include ActionController::Components
include ActionController::Verification
include ActionController::Streaming
+ include ActionController::AutoComplete
end
diff --git a/actionpack/lib/action_view/helpers/javascript_helper.rb b/actionpack/lib/action_view/helpers/javascript_helper.rb
index 31c15d222c..7b857f4f18 100644
--- a/actionpack/lib/action_view/helpers/javascript_helper.rb
+++ b/actionpack/lib/action_view/helpers/javascript_helper.rb
@@ -17,7 +17,7 @@ module ActionView
module JavascriptHelper
unless const_defined? :CALLBACKS
CALLBACKS = [ :uninitialized, :loading, :loaded, :interactive, :complete ]
- AJAX_OPTIONS = [ :url, :asynchronous, :method, :insertion, :form, :with ].concat(CALLBACKS)
+ AJAX_OPTIONS = [ :url, :asynchronous, :method, :insertion, :form, :with, :update ].concat(CALLBACKS)
JAVASCRIPT_PATH = File.join(File.dirname(__FILE__), 'javascripts')
end
@@ -220,39 +220,50 @@ module ActionView
# <tt>:update</tt>:: Specifies the DOM ID of the element whose
# innerHTML should be updated with the autocomplete
# entries returned by the Ajax request.
- # Defaults to field_id + '_autocomplete'
+ # Defaults to field_id + '_auto_complete'
# <tt>:with</tt>:: A Javascript expression specifying the
# parameters for the XMLHttpRequest. This defaults
# to 'value', which in the evaluated context
# refers to the new field value.
# <tt>:indicator</tt>:: Specifies the DOM ID of an elment which will be
# displayed while autocomplete is running.
- #
- def remote_autocomplete(field_id, options = {})
+ def auto_complete_field(field_id, options = {})
function = "new Ajax.Autocompleter("
function << "'#{field_id}', "
- function << "'" + (options[:update] || "#{field_id}_autocomplete") + "', "
+ function << "'" + (options[:update] || "#{field_id}_auto_complete") + "', "
function << "'#{url_for(options[:url])}'"
js_options = {}
- js_options[:callback] = "function(element, value) {return #{options[:with]}}" if options[:with]
+ js_options[:callback] = "function(element, value) { return #{options[:with]} }" if options[:with]
js_options[:indicator] = "'#{options[:indicator]}'" if options[:indicator]
function << (', ' + options_for_javascript(js_options) + ')')
-
+
javascript_tag(function)
end
# Use this method in your view to generate a return for the Ajax automplete requests.
#
- # Example Action:
- # @items = Item.find(:all, :conditions => [ 'LOWER(description) LIKE ?',
- # '%' + params[:for].downcase + '%' ], 'description ASC')
- # render :layout => false
- #
- # Example View:
- # <%= autocomplete_responder @items, 'description' %>
- def autocomplete_responder(entries, field, phrase = nil)
- "<ul>#{entries.map { |entry| '<li>' + (phrase ? highlight(entry[field],phrase) : h(entry[field])) + '</li>' }.join}</ul>" if entries
+ # Example action:
+ #
+ # def auto_complete_for_item_title
+ # @items = Item.find(:all, :conditions => [ 'LOWER(description) LIKE ?',
+ # '%' + params[:for].downcase + '%' ], 'description ASC')
+ # render :inline => '<%= auto_complete_result(@items, 'description') %>'
+ # end
+ #
+ # The auto_complete_result can of course also be called from a view belonging to the
+ # auto_complete action if you need to decorate it further.
+ def auto_complete_result(entries, field, phrase = nil)
+ return unless entries
+ items = entries.map { |entry| content_tag("li", phrase ? highlight(entry[field], phrase) : h(entry[field])) }
+ content_tag("ul", items)
+ end
+
+ def text_field_with_auto_complete(object, method, tag_options = {}, completion_options = {})
+ (completion_options[:skip_style] ? "" : auto_complete_stylesheet) +
+ text_field(object, method, tag_options) +
+ content_tag("div", "", :id => "#{object}_#{method}_auto_complete", :class => "auto_complete") +
+ auto_complete_field("#{object}_#{method}", { :url => { :action => "auto_complete_for_#{object}_#{method}" } }.update(completion_options))
end
# Returns a JavaScript snippet to be used on the Ajax callbacks for starting
@@ -347,6 +358,34 @@ module ActionView
callbacks
end
end
+
+ def auto_complete_stylesheet
+ content_tag("style", <<-EOT
+ div.auto_complete {
+ width: 350px;
+ }
+ div.auto_complete ul {
+ border:1px solid #888;
+ margin:0;
+ padding:0;
+ width:100%;
+ list-style-type:none;
+ }
+ div.auto_complete ul li {
+ margin:0;
+ padding:3px;
+ }
+ div.auto_complete ul li.selected {
+ background-color: #ffb;
+ }
+ div.auto_complete ul strong.highlight {
+ color: #800;
+ margin:0;
+ padding:0;
+ }
+ EOT
+ )
+ end
end
end
end