client_side_autocomplete 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in client_side_autocomplete.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 David Padilla
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,307 @@
1
+ # client_side_autocomplete
2
+
3
+ An easy way to use jQuery's autocomplete with Rails 3.1
4
+
5
+ Supports both ActiveRecord, [mongoid](http://github.com/mongoid/mongoid), and [MongoMapper](https://github.com/jnunemaker/mongomapper).
6
+
7
+ Works with [Formtastic](http://github.com/justinfrench/formtastic)
8
+ and [SimpleForm](https://github.com/plataformatec/simple_form)
9
+
10
+ ## Before you start
11
+
12
+ Make sure your project is using jQuery-UI and the autocomplete widget
13
+ before you continue.
14
+
15
+ You can find more info about that here:
16
+
17
+ * http://jquery.com/
18
+ * http://jqueryui.com/demos/autocomplete/
19
+ * http://github.com/rails/jquery-ujs
20
+
21
+ I'd encourage you to understand how to use those 3 amazing tools before attempting to use this gem.
22
+
23
+ ## Installing
24
+
25
+ Include the gem on your Gemfile
26
+
27
+ gem 'client_side_autocomplete'
28
+
29
+ Install it
30
+
31
+ bundle install
32
+
33
+ ## Usage ##
34
+
35
+ ### Rails 3.1 ###
36
+ The javascript file is served up in the asset pipeline. Add the
37
+ following to your `app/assets/javascripts/application.js` file.
38
+
39
+ ```javascript
40
+ //= require jquery
41
+ //= require jquery_ujs
42
+ //= require jquery-ui
43
+ //= require rails.autocomplete
44
+ ```
45
+
46
+ ### Model Example
47
+
48
+ Assuming you have a Brand model:
49
+
50
+ class Brand < ActiveRecord::Base
51
+ end
52
+
53
+ create_table :brand do |t|
54
+ t.column :name, :string
55
+ end
56
+
57
+ ### Controller
58
+
59
+ To set up the required action on your controller, all you have to do is call it with the class name and the method
60
+ as in the following example:
61
+
62
+ class ProductsController < Admin::BaseController
63
+ autocomplete :brand, :name
64
+ end
65
+
66
+ This will create an action _autocomplete_brand_name_ on your controller, don't forget to add it on your routes file
67
+
68
+ resources :products do
69
+ get :autocomplete_brand_name, :on => :collection
70
+ end
71
+
72
+ ### Options
73
+
74
+ #### :full => true
75
+
76
+ By default, the search starts from the beginning of the string you're searching for. If you want to do a full search, set the _full_ parameter to true.
77
+
78
+ class ProductsController < Admin::BaseController
79
+ autocomplete :brand, :name, :full => true
80
+ end
81
+
82
+ The following terms would match the query 'un':
83
+
84
+ * Luna
85
+ * Unacceptable
86
+ * Rerun
87
+
88
+ #### :full => false (default behavior)
89
+
90
+ Only the following terms mould match the query 'un':
91
+
92
+ * Unacceptable
93
+
94
+ #### :extra_data
95
+
96
+ By default, your search will only return the required columns from the database needed to populate your form, namely id and the column you are searching (name, in the above example).
97
+
98
+ Passing an array of attributes/column names to this option will fetch and return the specified data.
99
+
100
+ class ProductsController < Admin::BaseController
101
+ autocomplete :brand, :name, :extra_data => [:slogan]
102
+ end
103
+
104
+ #### :display_value
105
+
106
+ If you want to display a different version of what you're looking for, you can use the :display_value option.
107
+
108
+ This options receives a method name as the parameter, and that method will be called on the instance when displaying the results.
109
+
110
+ class Brand < ActiveRecord::Base
111
+ def funky_method
112
+ "#{self.name}.camelize"
113
+ end
114
+ end
115
+
116
+
117
+ class ProductsController < Admin::BaseController
118
+ autocomplete :brand, :name, :display_value => :funky_method
119
+ end
120
+
121
+ In the example above, you will search by _name_, but the autocomplete list will display the result of _funky_method_
122
+
123
+ This wouldn't really make much sense unless you use it with the "id_element" attribute. (See below)
124
+
125
+ Only the object's id and the column you are searching on will be returned in JSON, so if your display_value method requires another parameter, make sure to fetch it with the :extra_data option
126
+
127
+
128
+ #### :scopes
129
+ Added option to use scopes. Pass scopes in an array.
130
+ e.g `:scopes => [:scope1, :scope2]`
131
+
132
+ #### :column_name
133
+ By default autocomplete uses method name as column name. Now it can be specified using column_name options
134
+ `:column_name => 'name'`
135
+
136
+ #### json encoder
137
+ Autocomplete uses Yajl as JSON encoder/decoder, but you can specify your own
138
+
139
+ class ProductsController < Admin::BaseController
140
+ autocomplete :brand, :name do |items|
141
+ CustomJSON::Encoder.encode(items)
142
+ end
143
+ end
144
+
145
+ ### View
146
+
147
+ On your view, all you have to do is include the attribute autocomplete on the text field
148
+ using the url to the autocomplete action as the value.
149
+
150
+ form_for @product do |f|
151
+ f.autocomplete_field :brand_name, autocomplete_brand_name_products_path
152
+ end
153
+
154
+ This will generate an HTML tag that looks like:
155
+
156
+ <input type="text" data-autocomplete="products/autocomplete_brand_name">
157
+
158
+ If you are not using a FormBuilder (form_for) or you just want to include an autocomplete field without the form, you can use the
159
+ *autocomplete_field_tag* helper.
160
+
161
+ form_tag 'some/path'
162
+ autocomplete_field_tag 'address', '', address_autocomplete_path, :size => 75
163
+ end
164
+
165
+ Now your autocomplete code is unobtrusive, Rails 3 style.
166
+
167
+ ### Getting the object id
168
+
169
+ If you need to use the id of the selected object, you can use the *id_element* attribute too:
170
+
171
+ f.autocomplete_field :brand_name, autocomplete_brand_name_products_path, :id_element => '#some_element'
172
+
173
+ This will update the field with id *#some_element with the id of the selected object. The value for this option can be any jQuery selector.
174
+
175
+ ### Getting extra object data
176
+
177
+ If you need to extra data about the selected object, you can use the *:update_elements* HTML attribute.
178
+
179
+ The :update_elements attribute accepts a hash where the keys represent the object attribute/column data to use to update and the values are jQuery selectors to retrieve the HTML element to update:
180
+
181
+ f.autocomplete_field :brand_name, autocomplete_brand_name_products_path, :update_elements => {:id => '#id_element', :slogan => '#some_other_element'}
182
+
183
+ class ProductsController < Admin::BaseController
184
+ autocomplete :brand, :name, :extra_data => [:slogan]
185
+ end
186
+
187
+ The previous example would fetch the extra attribute slogan and update jQuery('#some_other_element') with the slogan value.
188
+
189
+ ### Running custom code on selection
190
+
191
+ A javascript event named *railsAutocomplete.select* is fired on the input field when a value is selected from the autocomplete drop down. If you need to do something more complex than update fields with data, you can hook into this event, like so:
192
+
193
+ $('#my_autocomplete_field').bind('railsAutocomplete.select', function(event, data){
194
+ /* Do something here */
195
+ alert(data.item.id);
196
+ });
197
+
198
+ ## Formtastic
199
+
200
+ If you are using [Formtastic](http://github.com/justinfrench/formtastic), you automatically get the *autocompleted_input* helper on *semantic_form_for*:
201
+
202
+ semantic_form_for @product do |f|
203
+ f.autocompleted_input :brand_name, :url => autocomplete_brand_name_products_path
204
+ end
205
+
206
+ The only difference with the original helper is that you must specify the autocomplete url using the *:url* option.
207
+
208
+ ## SimpleForm
209
+
210
+ If you want to use it with simple_form, all you have to do is use the
211
+ :as option on the input and set the autocomplete path with the :url
212
+ option.
213
+
214
+
215
+ simple_form_for @product do |form|
216
+ form.input :name
217
+ form.input :brand_name, :url => autocomplete_brand_name_products_path, :as => :autocomplete
218
+
219
+ # Cucumber
220
+
221
+ I have created a step to test your autocomplete with Cucumber and Capybara, all you have to do is add the following lines to your *env.rb* file:
222
+
223
+ require 'cucumber/autocomplete'
224
+
225
+ Then you'll have access to the following step:
226
+
227
+ I choose "([^"]*)" in the autocomplete list
228
+
229
+ An example on how to use it:
230
+
231
+ @javascript
232
+ Scenario: Autocomplete
233
+ Given the following brands exists:
234
+ | name |
235
+ | Alpha |
236
+ | Beta |
237
+ | Gamma |
238
+ And I go to the home page
239
+ And I fill in "Brand name" with "al"
240
+ And I choose "Alpha" in the autocomplete list
241
+ Then the "Brand name" field should contain "Alpha"
242
+
243
+ I have only tested this using Capybara, no idea if it works with something else, to see it in action, check the [example app](http://github.com/crowdint/rails3-jquery-autocomplete-app).
244
+
245
+ # Steak
246
+
247
+ I have created a helper to test your autocomplete with Steak and Capybara, all you have to do is add the following lines to your *acceptance_helper.rb* file:
248
+
249
+ require 'steak/autocomplete'
250
+
251
+ Then you'll have access to the following helper:
252
+
253
+ choose_autocomplete_result
254
+
255
+ An example on how to use it:
256
+
257
+ scenario "Autocomplete" do
258
+ lambda do
259
+ Brand.create! [
260
+ {:name => "Alpha"},
261
+ {:name => "Beta"},
262
+ {:name => "Gamma"}
263
+ ]
264
+ end.should change(Brand, :count).by(3)
265
+
266
+ visit home_page
267
+ fill_in "Brand name", :with => "al"
268
+ choose_autocomplete_result "Alpha"
269
+ find_field("Brand name").value.should include("Alpha")
270
+ end
271
+
272
+ I have only tested this using Capybara, no idea if it works with something else.
273
+
274
+ # Development
275
+
276
+ If you want to make changes to the gem, first install bundler 1.0.0:
277
+
278
+ gem install bundler
279
+
280
+ And then, install all your dependencies:
281
+
282
+ bundle install
283
+
284
+ ## Running the test suite
285
+
286
+ You need to have an instance of MongoDB running on your computer or all the mongo tests will fail miserably.
287
+
288
+ rake test
289
+
290
+ ## Integration tests
291
+
292
+ If you make changes or add features to the jQuery part, please make sure
293
+ you write a cucumber test for it.
294
+
295
+ You can find an example Rails app on the *integration* folder.
296
+
297
+ You can run the integration tests with the cucumber command while on the
298
+ integration folder:
299
+
300
+ cd integration
301
+ rake db:migrate
302
+ cucumber
303
+
304
+ # Thanks to
305
+
306
+ Author of rails3-jquery-autocomplete and [this list](https://github.com/crowdint/rails3-jquery-autocomplete/contributors)
307
+
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "client_side_autocomplete/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "client_side_autocomplete"
7
+ s.version = ClientSideAutocomplete::VERSION
8
+ s.authors = ["Shenouda Bertel"]
9
+ s.email = ["ShenoudaB@gmail.com"]
10
+ s.homepage = "http://mobithought.com"
11
+ s.summary = %q{Client Side AutoComplete}
12
+ s.description = %q{Client Side AutoComplete}
13
+
14
+ s.rubyforge_project = "client_side_autocomplete"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_dependency('rails', '~>3.1.0')
22
+
23
+ # specify any dependencies here; for example:
24
+ # s.add_development_dependency "rspec"
25
+ # s.add_runtime_dependency "rest-client"
26
+ end
@@ -0,0 +1,29 @@
1
+ require "client_side_autocomplete/version"
2
+ require 'client_side_autocomplete/form_helper'
3
+ require 'client_side_autocomplete/autocomplete'
4
+
5
+ module ClientSideAutocomplete
6
+ autoload :Orm , 'client_side_autocomplete/orm'
7
+ autoload :FormtasticPlugin , 'client_side_autocomplete/formtastic_plugin'
8
+ end
9
+
10
+ class ActionController::Base
11
+ include ClientSideAutocomplete::Autocomplete
12
+ end
13
+
14
+ #
15
+ # Load the formtastic plugin if using Formtastic
16
+ # TODO: Better way to load plugins
17
+ begin
18
+ require 'formtastic'
19
+ class Formtastic::FormBuilder < ActionView::Helpers::FormBuilder
20
+ include ClientSideAutocomplete::FormtasticPlugin
21
+ end
22
+ rescue LoadError
23
+ end
24
+
25
+ begin
26
+ require 'simple_form'
27
+ require 'client_side_autocomplete/simple_form_plugin'
28
+ rescue LoadError
29
+ end
@@ -0,0 +1,96 @@
1
+ module ClientSideAutocomplete
2
+ module Autocomplete
3
+ def self.included(target)
4
+ target.extend ClientSideAutocomplete::Autocomplete::ClassMethods
5
+
6
+ if defined?(Mongoid::Document)
7
+ target.send :include, ClientSideAutocomplete::Orm::Mongoid
8
+ elsif defined?(MongoMapper::Document)
9
+ target.send :include, ClientSideAutocomplete::Orm::MongoMapper
10
+ else
11
+ target.send :include, ClientSideAutocomplete::Orm::ActiveRecord
12
+ end
13
+ end
14
+
15
+ #
16
+ # Usage:
17
+ #
18
+ # class ProductsController < Admin::BaseController
19
+ # autocomplete :brand, :name
20
+ # end
21
+ #
22
+ # This will magically generate an action autocomplete_brand_name, so,
23
+ # don't forget to add it on your routes file
24
+ #
25
+ # resources :products do
26
+ # get :autocomplete_brand_name, :on => :collection
27
+ # end
28
+ #
29
+ # Now, on your view, all you have to do is have a text field like:
30
+ #
31
+ # f.text_field :brand_name, :autocomplete => autocomplete_brand_name_products_path
32
+ #
33
+ #
34
+ # Yajl is used by default to encode results, if you want to use a different encoder
35
+ # you can specify your custom encoder via block
36
+ #
37
+ # class ProductsController < Admin::BaseController
38
+ # autocomplete :brand, :name do |items|
39
+ # CustomJSONEncoder.encode(items)
40
+ # end
41
+ # end
42
+ #
43
+ module ClassMethods
44
+ def autocomplete(object, method, options = {})
45
+ define_method("autocomplete_#{object}_#{method}") do
46
+
47
+ method = options[:column_name] if options.has_key?(:column_name)
48
+
49
+ term = params[:term]
50
+
51
+ if term && !term.blank?
52
+ #allow specifying fully qualified class name for model object
53
+ class_name = options[:class_name] || object
54
+ items = get_autocomplete_items(:model => get_object(class_name), \
55
+ :options => options, :term => term, :method => method)
56
+ else
57
+ items = {}
58
+ end
59
+
60
+ render :json => json_for_autocomplete(items, options[:display_value] ||= method, options[:extra_data])
61
+ end
62
+ end
63
+ end
64
+
65
+ # Returns a limit that will be used on the query
66
+ def get_autocomplete_limit(options)
67
+ options[:limit] ||= 10
68
+ end
69
+
70
+ # Returns parameter model_sym as a constant
71
+ #
72
+ # get_object(:actor)
73
+ # # returns a Actor constant supposing it is already defined
74
+ #
75
+ def get_object(model_sym)
76
+ object = model_sym.to_s.camelize.constantize
77
+ end
78
+
79
+ #
80
+ # Returns a hash with three keys actually used by the Autocomplete jQuery-ui
81
+ # Can be overriden to show whatever you like
82
+ # Hash also includes a key/value pair for each method in extra_data
83
+ #
84
+ def json_for_autocomplete(items, method, extra_data=[])
85
+ items.collect do |item|
86
+ hash = {"id" => item.id.to_s, "label" => item.send(method), "value" => item.send(method)}
87
+ extra_data.each do |datum|
88
+ hash[datum] = item.send(datum)
89
+ end if extra_data
90
+ # TODO: Come back to remove this if clause when test suite is better
91
+ hash
92
+ end
93
+ end
94
+ end
95
+ end
96
+
@@ -0,0 +1,47 @@
1
+ module ActionView
2
+ module Helpers
3
+ module FormHelper
4
+ # Returns an input tag of the "text" type tailored for accessing a specified attribute (identified by +method+) and
5
+ # that is populated with jQuery's autocomplete plugin.
6
+ #
7
+ # ==== Examples
8
+ # autocomplete_field(:post, :title, author_autocomplete_path, :size => 20)
9
+ # # => <input type="text" id="post_title" name="post[title]" size="20" value="#{@post.title}" data-autocomplete="author/autocomplete"/>
10
+ #
11
+ def autocomplete_field(object_name, method, source, options ={})
12
+ options["data-autocomplete"] = source
13
+ text_field(object_name, method, rewrite_autocomplete_option(options))
14
+ end
15
+ end
16
+
17
+ module FormTagHelper
18
+ # Creates a standard text field that can be populated with jQuery's autocomplete plugin
19
+ #
20
+ # ==== Examples
21
+ # autocomplete_field_tag 'address', '', address_autocomplete_path, :size => 75
22
+ # # => <input id="address" name="address" size="75" type="text" value="" data-autocomplete="address/autocomplete"/>
23
+ #
24
+ def autocomplete_field_tag(name, value, source, options ={})
25
+ options["data-autocomplete"] = source
26
+ text_field_tag(name, value, rewrite_autocomplete_option(options))
27
+ end
28
+ end
29
+
30
+ #
31
+ # Method used to rename the autocomplete key to a more standard
32
+ # data-autocomplete key
33
+ #
34
+ private
35
+ def rewrite_autocomplete_option(options)
36
+ options["data-update-elements"] = JSON.generate(options.delete :update_elements) if options[:update_elements]
37
+ options["data-id-element"] = options.delete :id_element if options[:id_element]
38
+ options
39
+ end
40
+ end
41
+ end
42
+
43
+ class ActionView::Helpers::FormBuilder #:nodoc:
44
+ def autocomplete_field(method, source, options = {})
45
+ @template.autocomplete_field(@object_name, method, source, objectify_options(options))
46
+ end
47
+ end
@@ -0,0 +1,41 @@
1
+ module ClientSideAutocomplete
2
+ module FormtasticPlugin
3
+ def autocompleted_input(method, options = {})
4
+ if options.key?(:selected) || options.key?(:checked) || options.key?(:default)
5
+ ::ActiveSupport::Deprecation.warn(
6
+ "The :selected, :checked (and :default) options are deprecated in Formtastic and will be removed from 1.0. " <<
7
+ "Please set default values in your models (using an after_initialize callback) or in your controller set-up. " <<
8
+ "See http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html for more information.", caller)
9
+ end
10
+
11
+ options[:as] ||= "autocompleted_string"
12
+
13
+ html_class = [ options[:as], (options[:required] ? :required : :optional) ]
14
+ html_class << 'error' if @object && @object.respond_to?(:errors) && !@object.errors[method.to_sym].blank?
15
+
16
+ wrapper_html = options.delete(:wrapper_html) || {}
17
+ # wrapper_html[:id] ||= generate_html_id(method)
18
+ wrapper_html[:class] = (html_class << wrapper_html[:class]).flatten.compact.join(' ')
19
+
20
+ if options[:input_html] && options[:input_html][:id]
21
+ options[:label_html] ||= {}
22
+ options[:label_html][:for] ||= options[:input_html][:id]
23
+ end
24
+
25
+ # input_parts = self.class.inline_order.dup
26
+ # input_parts = input_parts - [:errors, :hints] if options[:as] == :hidden
27
+
28
+ list_item_content = input_parts.map do |type|
29
+ send(:"inline_#{type}_for", method, options)
30
+ end.compact.join("\n")
31
+
32
+ return template.content_tag(:li, Formtastic::Util.html_safe(list_item_content), wrapper_html)
33
+ end
34
+
35
+
36
+ protected
37
+ def autocompleted_string_input(method, options)
38
+ self.label(method, options_for_label(options)) << autocomplete_field(method, options.delete(:url), options)
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,8 @@
1
+ module ClientSideAutocomplete
2
+ module Orm
3
+ autoload :ActiveRecord , 'client_side_autocomplete/orm/active_record'
4
+ autoload :Mongoid , 'client_side_autocomplete/orm/mongoid'
5
+ autoload :MongoMapper , 'client_side_autocomplete/orm/mongo_mapper'
6
+ end
7
+ end
8
+
@@ -0,0 +1,47 @@
1
+ module ClientSideAutocomplete
2
+ module Orm
3
+ module ActiveRecord
4
+ def get_autocomplete_order(method, options, model=nil)
5
+ order = options[:order]
6
+
7
+ table_prefix = model ? "#{model.table_name}." : ""
8
+ order || "#{table_prefix}#{method} ASC"
9
+ end
10
+
11
+ def get_autocomplete_items(parameters)
12
+ model = parameters[:model]
13
+ term = parameters[:term]
14
+ method = parameters[:method]
15
+ options = parameters[:options]
16
+ scopes = Array(options[:scopes])
17
+ limit = get_autocomplete_limit(options)
18
+ order = get_autocomplete_order(method, options, model)
19
+
20
+
21
+ items = model.scoped
22
+
23
+ scopes.each { |scope| items = items.send(scope) } unless scopes.empty?
24
+
25
+ items = items.select(get_autocomplete_select_clause(model, method, options)) unless options[:full_model]
26
+ items = items.where(get_autocomplete_where_clause(model, term, method, options)).
27
+ limit(limit).order(order)
28
+ end
29
+
30
+ def get_autocomplete_select_clause(model, method, options)
31
+ table_name = model.table_name
32
+ (["#{table_name}.#{model.primary_key}", "#{table_name}.#{method}"] + (options[:extra_data].blank? ? [] : options[:extra_data]))
33
+ end
34
+
35
+ def get_autocomplete_where_clause(model, term, method, options)
36
+ table_name = model.table_name
37
+ is_full_search = options[:full]
38
+ like_clause = (postgres? ? 'ILIKE' : 'LIKE')
39
+ ["LOWER(#{table_name}.#{method}) #{like_clause} ?", "#{(is_full_search ? '%' : '')}#{term.downcase}%"]
40
+ end
41
+
42
+ def postgres?
43
+ defined?(PGConn)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,30 @@
1
+ module ClientSideAutocomplete
2
+ module Orm
3
+ module MongoMapper
4
+ def get_autocomplete_order(method, options, model=nil)
5
+ order = options[:order]
6
+ if order
7
+ order.split(',').collect do |fields|
8
+ sfields = fields.split
9
+ [sfields[0].downcase.to_sym, sfields[1].downcase.to_sym]
10
+ end
11
+ else
12
+ [[method.to_sym, :asc]]
13
+ end
14
+ end
15
+
16
+ def get_autocomplete_items(parameters)
17
+ model = parameters[:model]
18
+ method = parameters[:method]
19
+ options = parameters[:options]
20
+ is_full_search = options[:full]
21
+ term = parameters[:term]
22
+ limit = get_autocomplete_limit(options)
23
+ order = get_autocomplete_order(method, options)
24
+
25
+ search = (is_full_search ? '.*' : '^') + term + '.*'
26
+ items = model.where(method.to_sym => /#{search}/i).limit(limit).sort(order)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,30 @@
1
+ module ClientSideAutocomplete
2
+ module Orm
3
+ module Mongoid
4
+ def get_autocomplete_order(method, options, model=nil)
5
+ order = options[:order]
6
+ if order
7
+ order.split(',').collect do |fields|
8
+ sfields = fields.split
9
+ [sfields[0].downcase.to_sym, sfields[1].downcase.to_sym]
10
+ end
11
+ else
12
+ [[method.to_sym, :asc]]
13
+ end
14
+ end
15
+
16
+ def get_autocomplete_items(parameters)
17
+ model = parameters[:model]
18
+ method = parameters[:method]
19
+ options = parameters[:options]
20
+ is_full_search = options[:full]
21
+ term = parameters[:term]
22
+ limit = get_autocomplete_limit(options)
23
+ order = get_autocomplete_order(method, options)
24
+
25
+ search = (is_full_search ? '.*' : '^') + term + '.*'
26
+ items = model.where(method.to_sym => /#{search}/i).limit(limit).order_by(order)
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,25 @@
1
+ module SimpleForm
2
+ module Inputs
3
+ class AutocompleteInput < Base
4
+ def input
5
+ @builder.autocomplete_field(attribute_name, options[:url], input_html_options)
6
+ end
7
+
8
+ protected
9
+
10
+ def limit
11
+ column && column.limit
12
+ end
13
+
14
+ def has_placeholder?
15
+ placeholder_present?
16
+ end
17
+ end
18
+ end
19
+ end
20
+
21
+ module SimpleForm
22
+ class FormBuilder
23
+ map_type :autocomplete, :to => SimpleForm::Inputs::AutocompleteInput
24
+ end
25
+ end
@@ -0,0 +1,3 @@
1
+ module ClientSideAutocomplete
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,16 @@
1
+ /*
2
+ * Unobtrusive autocomplete
3
+ *
4
+ * To use it, you just have to include the HTML attribute autocomplete
5
+ * with the autocomplete URL as the value
6
+ *
7
+ * Example:
8
+ * <input type="text" data-autocomplete="/url/to/autocomplete">
9
+ *
10
+ * Optionally, you can use a jQuery selector to specify a field that can
11
+ * be updated with the element id whenever you find a matching value
12
+ *
13
+ * Example:
14
+ * <input type="text" data-autocomplete="/url/to/autocomplete" data-id-element="#id_field">
15
+ */
16
+ $(document).ready(function(){$("input[data-autocomplete]").railsAutocomplete()}),function(a){var b=null;a.fn.railsAutocomplete=function(){return this.live("focus",function(){this.railsAutoCompleter||(this.railsAutoCompleter=new a.railsAutocomplete(this))})},a.railsAutocomplete=function(a){_e=a,this.init(_e)},a.railsAutocomplete.fn=a.railsAutocomplete.prototype={railsAutocomplete:"0.0.1"},a.railsAutocomplete.fn.extend=a.railsAutocomplete.extend=a.extend,a.railsAutocomplete.fn.extend({init:function(a){function c(a){return b(a).pop().replace(/^\s+/,"")}function b(b){return b.split(a.delimiter)}a.delimiter=$(a).attr("data-delimiter")||null,$(a).autocomplete({source:function(b,d){$.getJSON($(a).attr("data-autocomplete"),{term:c(b.term)},function(){$(arguments[0]).each(function(b,c){var d={};d[c.id]=c,$(a).data(d)}),d.apply(null,arguments)})},search:function(){var a=c(this.value);if(a.length<2)return!1},focus:function(){return!1},select:function(c,d){var f=b(this.value);f.pop(),f.push(d.item.value);if(a.delimiter!=null)f.push(""),this.value=f.join(a.delimiter);else{this.value=f.join(""),$(this).attr("data-id-element")&&$($(this).attr("data-id-element")).val(d.item.id);if($(this).attr("data-update-elements")){var g=$(this).data(d.item.id.toString()),h=$.parseJSON($(this).attr("data-update-elements"));for(var i in h)$(h[i]).val(g[i])}}var j=this.value;$(this).bind("keyup.clearId",function(){$(this).val().trim()!=j.trim()&&($($(this).attr("data-id-element")).val(""),$(this).unbind("keyup.clearId"))}),$(this).trigger("railsAutocomplete.select",d);return!1}})}})}(jQuery)
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: client_side_autocomplete
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Shenouda Bertel
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-09-01 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rails
16
+ requirement: &70263840 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 3.1.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70263840
25
+ description: Client Side AutoComplete
26
+ email:
27
+ - ShenoudaB@gmail.com
28
+ executables: []
29
+ extensions: []
30
+ extra_rdoc_files: []
31
+ files:
32
+ - .gitignore
33
+ - Gemfile
34
+ - LICENSE
35
+ - README.markdown
36
+ - Rakefile
37
+ - client_side_autocomplete.gemspec
38
+ - lib/client_side_autocomplete.rb
39
+ - lib/client_side_autocomplete/autocomplete.rb
40
+ - lib/client_side_autocomplete/form_helper.rb
41
+ - lib/client_side_autocomplete/formtastic_plugin.rb
42
+ - lib/client_side_autocomplete/orm.rb
43
+ - lib/client_side_autocomplete/orm/active_record.rb
44
+ - lib/client_side_autocomplete/orm/mongo_mapper.rb
45
+ - lib/client_side_autocomplete/orm/mongoid.rb
46
+ - lib/client_side_autocomplete/simple_form_plugin.rb
47
+ - lib/client_side_autocomplete/version.rb
48
+ - vendor/assets/javascripts/rails.autocomplete.js
49
+ homepage: http://mobithought.com
50
+ licenses: []
51
+ post_install_message:
52
+ rdoc_options: []
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ! '>='
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ! '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ requirements: []
68
+ rubyforge_project: client_side_autocomplete
69
+ rubygems_version: 1.8.6
70
+ signing_key:
71
+ specification_version: 3
72
+ summary: Client Side AutoComplete
73
+ test_files: []