client_side_autocomplete 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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: []