wf-rails3-jquery-autocomplete 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +27 -0
- data/LICENSE +20 -0
- data/README.md +345 -0
- data/Rakefile +28 -0
- data/lib/assets/javascripts/autocomplete-rails-uncompressed.js +113 -0
- data/lib/assets/javascripts/autocomplete-rails.js +16 -0
- data/lib/cucumber/autocomplete.rb +6 -0
- data/lib/generators/autocomplete/install_generator.rb +14 -0
- data/lib/generators/autocomplete/uncompressed_generator.rb +14 -0
- data/lib/rails3-jquery-autocomplete.rb +23 -0
- data/lib/rails3-jquery-autocomplete/autocomplete.rb +110 -0
- data/lib/rails3-jquery-autocomplete/form_helper.rb +47 -0
- data/lib/rails3-jquery-autocomplete/formtastic.rb +41 -0
- data/lib/rails3-jquery-autocomplete/formtastic_plugin.rb +44 -0
- data/lib/rails3-jquery-autocomplete/orm.rb +8 -0
- data/lib/rails3-jquery-autocomplete/orm/active_record.rb +47 -0
- data/lib/rails3-jquery-autocomplete/orm/mongo_mapper.rb +30 -0
- data/lib/rails3-jquery-autocomplete/orm/mongoid.rb +34 -0
- data/lib/rails3-jquery-autocomplete/rails/engine.rb +5 -0
- data/lib/rails3-jquery-autocomplete/simple_form_plugin.rb +25 -0
- data/lib/rails3-jquery-autocomplete/version.rb +3 -0
- data/lib/steak/autocomplete.rb +12 -0
- metadata +210 -0
data/CHANGELOG.md
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
* 1.0.3 Fixed Formtastic 2.0 + Ruby 1.8.7 compat issue
|
4
|
+
* 1.0.2 Fixed issue #93, #94
|
5
|
+
* 1.0.1 Formtastic 2.0 compatibility fix
|
6
|
+
* 1.0.0 Rails 3.1 asset pipeline support
|
7
|
+
* 0.9.1 Fixes issues #96 and #32
|
8
|
+
* 0.9.0 Massive rewrite
|
9
|
+
* 0.8.0 Compressed JS file
|
10
|
+
* 0.7.5 Pull request #46
|
11
|
+
* 0.7.4 Allows Rails 3.1
|
12
|
+
* 0.7.3 MongoMapper
|
13
|
+
* 0.7.2 Steak helper
|
14
|
+
* 0.7.1 Fixed joined scopes (Issue #43)
|
15
|
+
* 0.7.0 Scopes
|
16
|
+
* 0.6.6 ILIKE for postgres
|
17
|
+
* 0.6.5 JS select event
|
18
|
+
* 0.6.4 Use YAJL instead of JSON
|
19
|
+
* 0.6.3 SimpleForm plugin
|
20
|
+
* 0.6.2 Fix Issue #8
|
21
|
+
* 0.6.1 Allow specifying fully qualified class name for model object as an option to autocomplete
|
22
|
+
* 0.6.0 JS Code cleanup
|
23
|
+
* 0.5.1 Add STI support
|
24
|
+
* 0.5.0 Formtastic support
|
25
|
+
* 0.4.0 MongoID support
|
26
|
+
* 0.3.6 Using .live() to put autocomplete on dynamic fields
|
27
|
+
|
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.
|
data/README.md
ADDED
@@ -0,0 +1,345 @@
|
|
1
|
+
# rails3-jquery-autocomplete
|
2
|
+
|
3
|
+
An easy way to use jQuery's autocomplete with Rails 3.
|
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
|
+
## ActiveRecord
|
11
|
+
|
12
|
+
You can find a [detailed example](http://github.com/crowdint/rails3-jquery-autocomplete-app)
|
13
|
+
on how to use this gem with ActiveRecord [here](http://github.com/crowdint/rails3-jquery-autocomplete-app).
|
14
|
+
|
15
|
+
## MongoID
|
16
|
+
|
17
|
+
You can find a [detailed example](http://github.com/crowdint/rails3-jquery-autocomplete-app/tree/mongoid)
|
18
|
+
on how to use this gem with MongoID [here](http://github.com/crowdint/rails3-jquery-autocomplete-app/tree/mongoid). (Same thing, different branch)
|
19
|
+
|
20
|
+
## Before you start
|
21
|
+
|
22
|
+
Make sure your project is using jQuery-UI and the autocomplete widget
|
23
|
+
before you continue.
|
24
|
+
|
25
|
+
You can find more info about that here:
|
26
|
+
|
27
|
+
* http://jquery.com/
|
28
|
+
* http://jqueryui.com/demos/autocomplete/
|
29
|
+
* http://github.com/rails/jquery-ujs
|
30
|
+
|
31
|
+
I'd encourage you to understand how to use those 3 amazing tools before attempting to use this gem.
|
32
|
+
|
33
|
+
## Installing
|
34
|
+
|
35
|
+
Include the gem on your Gemfile
|
36
|
+
|
37
|
+
gem 'rails3-jquery-autocomplete'
|
38
|
+
|
39
|
+
Install it
|
40
|
+
|
41
|
+
bundle install
|
42
|
+
|
43
|
+
### Rails 3.0.x
|
44
|
+
|
45
|
+
Run the generator
|
46
|
+
|
47
|
+
rails generate autocomplete:install
|
48
|
+
|
49
|
+
And include autocomplete-rails.js on your layouts
|
50
|
+
|
51
|
+
javascript_include_tag "autocomplete-rails.js"
|
52
|
+
|
53
|
+
### Rails 3.1.x
|
54
|
+
|
55
|
+
Just add it to your app/assets/javascripts/application.js file
|
56
|
+
|
57
|
+
//= require jquery
|
58
|
+
//= require jquery_ujs
|
59
|
+
//= require autocomplete-rails
|
60
|
+
|
61
|
+
## Upgrading from older versions
|
62
|
+
|
63
|
+
If you are upgrading from a previous version, run the generator after installing to replace the javascript file.
|
64
|
+
|
65
|
+
rails generate autocomplete:install
|
66
|
+
|
67
|
+
I'd recommend you do this every time you update to make sure you have the latest JS file.
|
68
|
+
|
69
|
+
## Uncompressed Javascript file
|
70
|
+
|
71
|
+
If you want to make changes to the JS file, you can install the
|
72
|
+
uncompressed version by running:
|
73
|
+
|
74
|
+
rails generate autocomplete:uncompressed
|
75
|
+
|
76
|
+
## Usage
|
77
|
+
|
78
|
+
### Model Example
|
79
|
+
|
80
|
+
Assuming you have a Brand model:
|
81
|
+
|
82
|
+
class Brand < ActiveRecord::Base
|
83
|
+
end
|
84
|
+
|
85
|
+
create_table :brand do |t|
|
86
|
+
t.column :name, :string
|
87
|
+
end
|
88
|
+
|
89
|
+
### Controller
|
90
|
+
|
91
|
+
To set up the required action on your controller, all you have to do is call it with the class name and the method
|
92
|
+
as in the following example:
|
93
|
+
|
94
|
+
class ProductsController < Admin::BaseController
|
95
|
+
autocomplete :brand, :name
|
96
|
+
end
|
97
|
+
|
98
|
+
This will create an action _autocomplete_brand_name_ on your controller, don't forget to add it on your routes file
|
99
|
+
|
100
|
+
resources :products do
|
101
|
+
get :autocomplete_brand_name, :on => :collection
|
102
|
+
end
|
103
|
+
|
104
|
+
### Options
|
105
|
+
|
106
|
+
#### :full => true
|
107
|
+
|
108
|
+
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.
|
109
|
+
|
110
|
+
class ProductsController < Admin::BaseController
|
111
|
+
autocomplete :brand, :name, :full => true
|
112
|
+
end
|
113
|
+
|
114
|
+
The following terms would match the query 'un':
|
115
|
+
|
116
|
+
* Luna
|
117
|
+
* Unacceptable
|
118
|
+
* Rerun
|
119
|
+
|
120
|
+
#### :full => false (default behavior)
|
121
|
+
|
122
|
+
Only the following terms mould match the query 'un':
|
123
|
+
|
124
|
+
* Unacceptable
|
125
|
+
|
126
|
+
#### :extra_data
|
127
|
+
|
128
|
+
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).
|
129
|
+
|
130
|
+
Passing an array of attributes/column names to this option will fetch and return the specified data.
|
131
|
+
|
132
|
+
class ProductsController < Admin::BaseController
|
133
|
+
autocomplete :brand, :name, :extra_data => [:slogan]
|
134
|
+
end
|
135
|
+
|
136
|
+
#### :display_value
|
137
|
+
|
138
|
+
If you want to display a different version of what you're looking for, you can use the :display_value option.
|
139
|
+
|
140
|
+
This options receives a method name as the parameter, and that method will be called on the instance when displaying the results.
|
141
|
+
|
142
|
+
class Brand < ActiveRecord::Base
|
143
|
+
def funky_method
|
144
|
+
"#{self.name}.camelize"
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
|
149
|
+
class ProductsController < Admin::BaseController
|
150
|
+
autocomplete :brand, :name, :display_value => :funky_method
|
151
|
+
end
|
152
|
+
|
153
|
+
In the example above, you will search by _name_, but the autocomplete list will display the result of _funky_method_
|
154
|
+
|
155
|
+
This wouldn't really make much sense unless you use it with the "id_element" attribute. (See below)
|
156
|
+
|
157
|
+
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
|
158
|
+
|
159
|
+
|
160
|
+
#### :scopes
|
161
|
+
Added option to use scopes. Pass scopes in an array.
|
162
|
+
e.g `:scopes => [:scope1, :scope2]`
|
163
|
+
|
164
|
+
#### :column_name
|
165
|
+
By default autocomplete uses method name as column name. Now it can be specified using column_name options
|
166
|
+
`:column_name => 'name'`
|
167
|
+
|
168
|
+
#### json encoder
|
169
|
+
Autocomplete uses Yajl as JSON encoder/decoder, but you can specify your own
|
170
|
+
|
171
|
+
class ProductsController < Admin::BaseController
|
172
|
+
autocomplete :brand, :name do |items|
|
173
|
+
CustomJSON::Encoder.encode(items)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
### View
|
178
|
+
|
179
|
+
On your view, all you have to do is include the attribute autocomplete on the text field
|
180
|
+
using the url to the autocomplete action as the value.
|
181
|
+
|
182
|
+
form_for @product do |f|
|
183
|
+
f.autocomplete_field :brand_name, autocomplete_brand_name_products_path
|
184
|
+
end
|
185
|
+
|
186
|
+
This will generate an HTML tag that looks like:
|
187
|
+
|
188
|
+
<input type="text" data-autocomplete="products/autocomplete_brand_name">
|
189
|
+
|
190
|
+
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
|
191
|
+
*autocomplete_field_tag* helper.
|
192
|
+
|
193
|
+
form_tag 'some/path'
|
194
|
+
autocomplete_field_tag 'address', '', address_autocomplete_path, :size => 75
|
195
|
+
end
|
196
|
+
|
197
|
+
Now your autocomplete code is unobtrusive, Rails 3 style.
|
198
|
+
|
199
|
+
### Getting the object id
|
200
|
+
|
201
|
+
If you need to use the id of the selected object, you can use the *id_element* attribute too:
|
202
|
+
|
203
|
+
f.autocomplete_field :brand_name, autocomplete_brand_name_products_path, :id_element => '#some_element'
|
204
|
+
|
205
|
+
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.
|
206
|
+
|
207
|
+
### Getting extra object data
|
208
|
+
|
209
|
+
If you need to extra data about the selected object, you can use the *:update_elements* HTML attribute.
|
210
|
+
|
211
|
+
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:
|
212
|
+
|
213
|
+
f.autocomplete_field :brand_name, autocomplete_brand_name_products_path, :update_elements => {:id => '#id_element', :slogan => '#some_other_element'}
|
214
|
+
|
215
|
+
class ProductsController < Admin::BaseController
|
216
|
+
autocomplete :brand, :name, :extra_data => [:slogan]
|
217
|
+
end
|
218
|
+
|
219
|
+
The previous example would fetch the extra attribute slogan and update jQuery('#some_other_element') with the slogan value.
|
220
|
+
|
221
|
+
### Running custom code on selection
|
222
|
+
|
223
|
+
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:
|
224
|
+
|
225
|
+
$('#my_autocomplete_field').bind('railsAutocomplete.select', function(event, data){
|
226
|
+
/* Do something here */
|
227
|
+
alert(data.item.id);
|
228
|
+
});
|
229
|
+
|
230
|
+
## Formtastic
|
231
|
+
|
232
|
+
If you are using [Formtastic](http://github.com/justinfrench/formtastic), you automatically get the *autocompleted_input* helper on *semantic_form_for*:
|
233
|
+
|
234
|
+
semantic_form_for @product do |f|
|
235
|
+
f.input :brand_name, :as => :autocomplete, :url => autocomplete_brand_name_products_path
|
236
|
+
end
|
237
|
+
|
238
|
+
The only difference with the original helper is that you must specify the autocomplete url using the *:url* option.
|
239
|
+
|
240
|
+
## SimpleForm
|
241
|
+
|
242
|
+
If you want to use it with simple_form, all you have to do is use the
|
243
|
+
:as option on the input and set the autocomplete path with the :url
|
244
|
+
option.
|
245
|
+
|
246
|
+
|
247
|
+
simple_form_for @product do |form|
|
248
|
+
form.input :name
|
249
|
+
form.input :brand_name, :url => autocomplete_brand_name_products_path, :as => :autocomplete
|
250
|
+
|
251
|
+
# Cucumber
|
252
|
+
|
253
|
+
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:
|
254
|
+
|
255
|
+
require 'cucumber/autocomplete'
|
256
|
+
|
257
|
+
Then you'll have access to the following step:
|
258
|
+
|
259
|
+
I choose "([^"]*)" in the autocomplete list
|
260
|
+
|
261
|
+
An example on how to use it:
|
262
|
+
|
263
|
+
@javascript
|
264
|
+
Scenario: Autocomplete
|
265
|
+
Given the following brands exists:
|
266
|
+
| name |
|
267
|
+
| Alpha |
|
268
|
+
| Beta |
|
269
|
+
| Gamma |
|
270
|
+
And I go to the home page
|
271
|
+
And I fill in "Brand name" with "al"
|
272
|
+
And I choose "Alpha" in the autocomplete list
|
273
|
+
Then the "Brand name" field should contain "Alpha"
|
274
|
+
|
275
|
+
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).
|
276
|
+
|
277
|
+
# Steak
|
278
|
+
|
279
|
+
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:
|
280
|
+
|
281
|
+
require 'steak/autocomplete'
|
282
|
+
|
283
|
+
Then you'll have access to the following helper:
|
284
|
+
|
285
|
+
choose_autocomplete_result
|
286
|
+
|
287
|
+
An example on how to use it:
|
288
|
+
|
289
|
+
scenario "Autocomplete" do
|
290
|
+
lambda do
|
291
|
+
Brand.create! [
|
292
|
+
{:name => "Alpha"},
|
293
|
+
{:name => "Beta"},
|
294
|
+
{:name => "Gamma"}
|
295
|
+
]
|
296
|
+
end.should change(Brand, :count).by(3)
|
297
|
+
|
298
|
+
visit home_page
|
299
|
+
fill_in "Brand name", :with => "al"
|
300
|
+
choose_autocomplete_result "Alpha"
|
301
|
+
find_field("Brand name").value.should include("Alpha")
|
302
|
+
end
|
303
|
+
|
304
|
+
I have only tested this using Capybara, no idea if it works with something else.
|
305
|
+
|
306
|
+
# Development
|
307
|
+
|
308
|
+
If you want to make changes to the gem, first install bundler 1.0.0:
|
309
|
+
|
310
|
+
gem install bundler
|
311
|
+
|
312
|
+
And then, install all your dependencies:
|
313
|
+
|
314
|
+
bundle install
|
315
|
+
|
316
|
+
## Running the test suite
|
317
|
+
|
318
|
+
You need to have an instance of MongoDB running on your computer or all the mongo tests will fail miserably.
|
319
|
+
|
320
|
+
rake test
|
321
|
+
|
322
|
+
## Integration tests
|
323
|
+
|
324
|
+
If you make changes or add features to the jQuery part, please make sure
|
325
|
+
you write a cucumber test for it.
|
326
|
+
|
327
|
+
You can find an example Rails app on the *integration* folder.
|
328
|
+
|
329
|
+
You can run the integration tests with the cucumber command while on the
|
330
|
+
integration folder:
|
331
|
+
|
332
|
+
cd integration
|
333
|
+
rake db:migrate
|
334
|
+
cucumber
|
335
|
+
|
336
|
+
# Thanks to
|
337
|
+
|
338
|
+
Everyone on [this list](https://github.com/crowdint/rails3-jquery-autocomplete/contributors)
|
339
|
+
|
340
|
+
# About the Author
|
341
|
+
|
342
|
+
[Crowd Interactive](http://www.crowdint.com) is an American web design and development company that happens to work in Colima, Mexico.
|
343
|
+
We specialize in building and growing online retail stores. We don’t work with everyone – just companies we believe in. Call us today to see if there’s a fit.
|
344
|
+
Find more info [here](http://www.crowdint.com)!
|
345
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
require 'rake/testtask'
|
5
|
+
require 'rcov/rcovtask'
|
6
|
+
|
7
|
+
task :default => [:uglify, :test]
|
8
|
+
|
9
|
+
Rake::TestTask.new(:test) do |test|
|
10
|
+
test.libs << 'lib' << 'test'
|
11
|
+
test.pattern = 'test/**/*_test.rb'
|
12
|
+
test.verbose = true
|
13
|
+
end
|
14
|
+
|
15
|
+
task :uglify do
|
16
|
+
require 'uglifier'
|
17
|
+
file_folder = "lib/assets/javascripts"
|
18
|
+
File.open("#{file_folder}/autocomplete-rails.js", "w") do |f|
|
19
|
+
f << Uglifier.compile(File.read("#{file_folder}/autocomplete-rails-uncompressed.js"))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
Rcov::RcovTask.new do |t|
|
24
|
+
t.libs << "test"
|
25
|
+
t.test_files = FileList['test/**/*_test.rb']
|
26
|
+
t.rcov_opts = %w{--exclude \/gems\/}
|
27
|
+
t.verbose = true
|
28
|
+
end
|
@@ -0,0 +1,113 @@
|
|
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
|
+
|
17
|
+
$(document).ready(function(){
|
18
|
+
$('input[data-autocomplete]').railsAutocomplete();
|
19
|
+
});
|
20
|
+
|
21
|
+
(function(jQuery)
|
22
|
+
{
|
23
|
+
var self = null;
|
24
|
+
jQuery.fn.railsAutocomplete = function() {
|
25
|
+
return this.live('focus',function() {
|
26
|
+
if (!this.railsAutoCompleter) {
|
27
|
+
this.railsAutoCompleter = new jQuery.railsAutocomplete(this);
|
28
|
+
}
|
29
|
+
});
|
30
|
+
};
|
31
|
+
|
32
|
+
jQuery.railsAutocomplete = function (e) {
|
33
|
+
_e = e;
|
34
|
+
this.init(_e);
|
35
|
+
};
|
36
|
+
|
37
|
+
jQuery.railsAutocomplete.fn = jQuery.railsAutocomplete.prototype = {
|
38
|
+
railsAutocomplete: '0.0.1'
|
39
|
+
};
|
40
|
+
|
41
|
+
jQuery.railsAutocomplete.fn.extend = jQuery.railsAutocomplete.extend = jQuery.extend;
|
42
|
+
jQuery.railsAutocomplete.fn.extend({
|
43
|
+
init: function(e) {
|
44
|
+
e.delimiter = $(e).attr('data-delimiter') || null;
|
45
|
+
function split( val ) {
|
46
|
+
return val.split( e.delimiter );
|
47
|
+
}
|
48
|
+
function extractLast( term ) {
|
49
|
+
return split( term ).pop().replace(/^\s+/,"");
|
50
|
+
}
|
51
|
+
|
52
|
+
$(e).autocomplete({
|
53
|
+
source: function( request, response ) {
|
54
|
+
$.getJSON( $(e).attr('data-autocomplete'), {
|
55
|
+
term: extractLast( request.term )
|
56
|
+
}, function() {
|
57
|
+
$(arguments[0]).each(function(i, el) {
|
58
|
+
var obj = {};
|
59
|
+
obj[el.id] = el;
|
60
|
+
$(e).data(obj);
|
61
|
+
});
|
62
|
+
response.apply(null, arguments);
|
63
|
+
});
|
64
|
+
},
|
65
|
+
search: function() {
|
66
|
+
// custom minLength
|
67
|
+
var term = extractLast( this.value );
|
68
|
+
if ( term.length < 2 ) {
|
69
|
+
return false;
|
70
|
+
}
|
71
|
+
},
|
72
|
+
focus: function() {
|
73
|
+
// prevent value inserted on focus
|
74
|
+
return false;
|
75
|
+
},
|
76
|
+
select: function( event, ui ) {
|
77
|
+
var terms = split( this.value );
|
78
|
+
// remove the current input
|
79
|
+
terms.pop();
|
80
|
+
// add the selected item
|
81
|
+
terms.push( ui.item.value );
|
82
|
+
// add placeholder to get the comma-and-space at the end
|
83
|
+
if (e.delimiter != null) {
|
84
|
+
terms.push( "" );
|
85
|
+
this.value = terms.join( e.delimiter );
|
86
|
+
} else {
|
87
|
+
this.value = terms.join("");
|
88
|
+
if ($(this).attr('data-id-element')) {
|
89
|
+
$($(this).attr('data-id-element')).val(ui.item.id);
|
90
|
+
}
|
91
|
+
if ($(this).attr('data-update-elements')) {
|
92
|
+
var data = $(this).data(ui.item.id.toString());
|
93
|
+
var update_elements = $.parseJSON($(this).attr("data-update-elements"));
|
94
|
+
for (var key in update_elements) {
|
95
|
+
$(update_elements[key]).val(data[key]);
|
96
|
+
}
|
97
|
+
}
|
98
|
+
}
|
99
|
+
var remember_string = this.value;
|
100
|
+
$(this).bind('keyup.clearId', function(){
|
101
|
+
if($(this).val().trim() != remember_string.trim()){
|
102
|
+
$($(this).attr('data-id-element')).val("");
|
103
|
+
$(this).unbind('keyup.clearId');
|
104
|
+
}
|
105
|
+
});
|
106
|
+
$(this).trigger('railsAutocomplete.select', ui);
|
107
|
+
|
108
|
+
return false;
|
109
|
+
}
|
110
|
+
});
|
111
|
+
}
|
112
|
+
});
|
113
|
+
})(jQuery);
|
@@ -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 b(b){return b.split(a.delimiter)}function c(a){return b(a).pop().replace(/^\s+/,"")}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;return $(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),!1}})}})}(jQuery)
|
@@ -0,0 +1,6 @@
|
|
1
|
+
Given /^I choose "([^"]*)" in the autocomplete list$/ do |text|
|
2
|
+
page.execute_script %Q{ $('input[data-autocomplete]').trigger("focus") }
|
3
|
+
page.execute_script %Q{ $('input[data-autocomplete]').trigger("keydown") }
|
4
|
+
sleep 1
|
5
|
+
page.execute_script %Q{ $('.ui-menu-item a:contains("#{text}")').trigger("mouseenter").trigger("click"); }
|
6
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
|
3
|
+
module Autocomplete
|
4
|
+
class InstallGenerator < Rails::Generators::Base
|
5
|
+
def install
|
6
|
+
# Copy the unobtrusive JS file
|
7
|
+
copy_file('autocomplete-rails.js', 'public/javascripts/autocomplete-rails.js')
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.source_root
|
11
|
+
File.join(File.dirname(__FILE__), '..', '..', 'assets', 'javascripts')
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
|
3
|
+
module Autocomplete
|
4
|
+
class UncompressedGenerator < Rails::Generators::Base
|
5
|
+
def install
|
6
|
+
# Copy the unobtrusive JS file
|
7
|
+
copy_file('autocomplete-rails-uncompressed.js', 'public/javascripts/autocomplete-rails.js')
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.source_root
|
11
|
+
File.join(File.dirname(__FILE__), '..', '..', 'assets', 'javascripts')
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rails3-jquery-autocomplete/form_helper'
|
2
|
+
require 'rails3-jquery-autocomplete/autocomplete'
|
3
|
+
|
4
|
+
module Rails3JQueryAutocomplete
|
5
|
+
autoload :Orm , 'rails3-jquery-autocomplete/orm'
|
6
|
+
autoload :FormtasticPlugin , 'rails3-jquery-autocomplete/formtastic_plugin'
|
7
|
+
|
8
|
+
unless ::Rails.version < "3.1"
|
9
|
+
require 'rails3-jquery-autocomplete/rails/engine'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class ActionController::Base
|
14
|
+
include Rails3JQueryAutocomplete::Autocomplete
|
15
|
+
end
|
16
|
+
|
17
|
+
require 'rails3-jquery-autocomplete/formtastic'
|
18
|
+
|
19
|
+
begin
|
20
|
+
require 'simple_form'
|
21
|
+
require 'rails3-jquery-autocomplete/simple_form_plugin'
|
22
|
+
rescue LoadError
|
23
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
module Rails3JQueryAutocomplete
|
2
|
+
module Autocomplete
|
3
|
+
def self.included(target)
|
4
|
+
target.extend Rails3JQueryAutocomplete::Autocomplete::ClassMethods
|
5
|
+
|
6
|
+
target.send :include, Rails3JQueryAutocomplete::Orm::Mongoid if defined?(Mongoid::Document)
|
7
|
+
target.send :include, Rails3JQueryAutocomplete::Orm::MongoMapper if defined?(MongoMapper::Document)
|
8
|
+
target.send :include, Rails3JQueryAutocomplete::Orm::ActiveRecord
|
9
|
+
end
|
10
|
+
|
11
|
+
#
|
12
|
+
# Usage:
|
13
|
+
#
|
14
|
+
# class ProductsController < Admin::BaseController
|
15
|
+
# autocomplete :brand, :name
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# This will magically generate an action autocomplete_brand_name, so,
|
19
|
+
# don't forget to add it on your routes file
|
20
|
+
#
|
21
|
+
# resources :products do
|
22
|
+
# get :autocomplete_brand_name, :on => :collection
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# Now, on your view, all you have to do is have a text field like:
|
26
|
+
#
|
27
|
+
# f.text_field :brand_name, :autocomplete => autocomplete_brand_name_products_path
|
28
|
+
#
|
29
|
+
#
|
30
|
+
# Yajl is used by default to encode results, if you want to use a different encoder
|
31
|
+
# you can specify your custom encoder via block
|
32
|
+
#
|
33
|
+
# class ProductsController < Admin::BaseController
|
34
|
+
# autocomplete :brand, :name do |items|
|
35
|
+
# CustomJSONEncoder.encode(items)
|
36
|
+
# end
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
module ClassMethods
|
40
|
+
def autocomplete(object, method, options = {})
|
41
|
+
define_method("get_prefix") do |model|
|
42
|
+
if model.superclass == ActiveRecord::Base
|
43
|
+
'active_record'
|
44
|
+
elsif model.superclass == Object && model.include?(Mongoid::Document)
|
45
|
+
'mongoid'
|
46
|
+
elsif model.superclass == Object && model.include?(MongoMapper::Document)
|
47
|
+
'mongo_mapper'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
define_method("get_autocomplete_order") do |method, options, model=nil|
|
52
|
+
method("#{get_prefix(get_object(options[:class_name] || object))}_get_autocomplete_order").call(method, options, model)
|
53
|
+
end
|
54
|
+
|
55
|
+
define_method("get_autocomplete_items") do |parameters|
|
56
|
+
method("#{get_prefix(get_object(options[:class_name] || object))}_get_autocomplete_items").call(parameters)
|
57
|
+
end
|
58
|
+
|
59
|
+
define_method("autocomplete_#{object}_#{method}") do
|
60
|
+
|
61
|
+
method = options[:column_name] if options.has_key?(:column_name)
|
62
|
+
|
63
|
+
term = params[:term]
|
64
|
+
|
65
|
+
if term && !term.blank?
|
66
|
+
#allow specifying fully qualified class name for model object
|
67
|
+
class_name = options[:class_name] || object
|
68
|
+
items = get_autocomplete_items(:model => get_object(class_name), \
|
69
|
+
:options => options, :term => term, :method => method)
|
70
|
+
else
|
71
|
+
items = {}
|
72
|
+
end
|
73
|
+
|
74
|
+
render :json => json_for_autocomplete(items, options[:display_value] ||= method, options[:extra_data])
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# Returns a limit that will be used on the query
|
80
|
+
def get_autocomplete_limit(options)
|
81
|
+
options[:limit] ||= 10
|
82
|
+
end
|
83
|
+
|
84
|
+
# Returns parameter model_sym as a constant
|
85
|
+
#
|
86
|
+
# get_object(:actor)
|
87
|
+
# # returns a Actor constant supposing it is already defined
|
88
|
+
#
|
89
|
+
def get_object(model_sym)
|
90
|
+
object = model_sym.to_s.camelize.constantize
|
91
|
+
end
|
92
|
+
|
93
|
+
#
|
94
|
+
# Returns a hash with three keys actually used by the Autocomplete jQuery-ui
|
95
|
+
# Can be overriden to show whatever you like
|
96
|
+
# Hash also includes a key/value pair for each method in extra_data
|
97
|
+
#
|
98
|
+
def json_for_autocomplete(items, method, extra_data=[])
|
99
|
+
items.collect do |item|
|
100
|
+
hash = {"id" => item.id.to_s, "label" => item.send(method), "value" => item.send(method)}
|
101
|
+
extra_data.each do |datum|
|
102
|
+
hash[datum] = item.send(datum)
|
103
|
+
end if extra_data
|
104
|
+
# TODO: Come back to remove this if clause when test suite is better
|
105
|
+
hash
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
@@ -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
|
+
#
|
2
|
+
# Load the formtastic plugin if using Formtastic
|
3
|
+
#
|
4
|
+
begin
|
5
|
+
require 'formtastic'
|
6
|
+
begin
|
7
|
+
require "formtastic/version"
|
8
|
+
rescue LoadError
|
9
|
+
end
|
10
|
+
|
11
|
+
if defined?(Formtastic::VERSION)
|
12
|
+
#
|
13
|
+
# Formtastic 2.x
|
14
|
+
#
|
15
|
+
|
16
|
+
module Formtastic
|
17
|
+
module Inputs
|
18
|
+
class AutocompleteInput
|
19
|
+
include Base
|
20
|
+
include Base::Stringish
|
21
|
+
|
22
|
+
def to_html
|
23
|
+
input_wrapping do
|
24
|
+
label_html <<
|
25
|
+
builder.autocomplete_field(method, options.delete(:url), input_html_options)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
else
|
32
|
+
|
33
|
+
#
|
34
|
+
# Formtastic 1.x
|
35
|
+
#
|
36
|
+
class Formtastic::SemanticFormBuilder < ActionView::Helpers::FormBuilder
|
37
|
+
include Rails3JQueryAutocomplete::FormtasticPlugin
|
38
|
+
end
|
39
|
+
end
|
40
|
+
rescue LoadError
|
41
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Rails3JQueryAutocomplete
|
2
|
+
module FormtasticPlugin
|
3
|
+
def autocomplete_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[:required] = method_required?(method) unless options.key?(:required)
|
12
|
+
options[:as] ||= "autocompleted_string"
|
13
|
+
|
14
|
+
html_class = [ options[:as], (options[:required] ? :required : :optional) ]
|
15
|
+
html_class << 'error' if @object && @object.respond_to?(:errors) && !@object.errors[method.to_sym].blank?
|
16
|
+
|
17
|
+
wrapper_html = options.delete(:wrapper_html) || {}
|
18
|
+
wrapper_html[:id] ||= generate_html_id(method)
|
19
|
+
wrapper_html[:class] = (html_class << wrapper_html[:class]).flatten.compact.join(' ')
|
20
|
+
|
21
|
+
if options[:input_html] && options[:input_html][:id]
|
22
|
+
options[:label_html] ||= {}
|
23
|
+
options[:label_html][:for] ||= options[:input_html][:id]
|
24
|
+
end
|
25
|
+
|
26
|
+
input_parts = self.class.inline_order.dup
|
27
|
+
input_parts = input_parts - [:errors, :hints] if options[:as] == :hidden
|
28
|
+
|
29
|
+
list_item_content = input_parts.map do |type|
|
30
|
+
send(:"inline_#{type}_for", method, options)
|
31
|
+
end.compact.join("\n")
|
32
|
+
|
33
|
+
return template.content_tag(:li, Formtastic::Util.html_safe(list_item_content), wrapper_html)
|
34
|
+
end
|
35
|
+
|
36
|
+
alias_method :autocompleted_input, :autocomplete_input
|
37
|
+
|
38
|
+
|
39
|
+
protected
|
40
|
+
def autocompleted_string_input(method, options)
|
41
|
+
self.label(method, options_for_label(options)) << autocomplete_field(method, options.delete(:url), options)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
module Rails3JQueryAutocomplete
|
2
|
+
module Orm
|
3
|
+
autoload :ActiveRecord , 'rails3-jquery-autocomplete/orm/active_record'
|
4
|
+
autoload :Mongoid , 'rails3-jquery-autocomplete/orm/mongoid'
|
5
|
+
autoload :MongoMapper , 'rails3-jquery-autocomplete/orm/mongo_mapper'
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Rails3JQueryAutocomplete
|
2
|
+
module Orm
|
3
|
+
module ActiveRecord
|
4
|
+
def active_record_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 active_record_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 = active_record_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 Rails3JQueryAutocomplete
|
2
|
+
module Orm
|
3
|
+
module MongoMapper
|
4
|
+
def mongo_mapper_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 mongo_mapper_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 = mongo_mapper_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,34 @@
|
|
1
|
+
module Rails3JQueryAutocomplete
|
2
|
+
module Orm
|
3
|
+
module Mongoid
|
4
|
+
def mongoid_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 mongoid_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 = mongoid_get_autocomplete_order(method, options)
|
24
|
+
|
25
|
+
if is_full_search
|
26
|
+
search = '.*' + term + '.*'
|
27
|
+
else
|
28
|
+
search = '^' + term
|
29
|
+
end
|
30
|
+
items = model.where(method.to_sym => /#{search}/i).limit(limit).order_by(order)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
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,12 @@
|
|
1
|
+
module Steak
|
2
|
+
module Autocomplete
|
3
|
+
def choose_autocomplete_result(text, input_id="input[data-autocomplete]")
|
4
|
+
page.execute_script %Q{ $('#{input_id}').trigger("focus") }
|
5
|
+
page.execute_script %Q{ $('#{input_id}').trigger("keydown") }
|
6
|
+
sleep 1
|
7
|
+
page.execute_script %Q{ $('.ui-menu-item a:contains("#{text}")').trigger("mouseenter").trigger("click"); }
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
RSpec.configuration.include Steak::Autocomplete, :type => :acceptance
|
metadata
ADDED
@@ -0,0 +1,210 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: wf-rails3-jquery-autocomplete
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.4
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- David Padilla
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-09-18 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rails
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '3.0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '3.0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: sqlite3-ruby
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: mongoid
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 2.0.0
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 2.0.0
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: mongo_mapper
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0.9'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0.9'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: bson_ext
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ~>
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: 1.3.0
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 1.3.0
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: shoulda
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ~>
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: 2.11.1
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ~>
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 2.11.1
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: uglifier
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: rr
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ! '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
type: :development
|
135
|
+
prerelease: false
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
- !ruby/object:Gem::Dependency
|
143
|
+
name: rcov
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
145
|
+
none: false
|
146
|
+
requirements:
|
147
|
+
- - ! '>='
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
type: :development
|
151
|
+
prerelease: false
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - ! '>='
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0'
|
158
|
+
description: Use jQuery's autocomplete plugin with Rails 3.
|
159
|
+
email: david.padilla@crowdint.com
|
160
|
+
executables: []
|
161
|
+
extensions: []
|
162
|
+
extra_rdoc_files: []
|
163
|
+
files:
|
164
|
+
- lib/assets/javascripts/autocomplete-rails-uncompressed.js
|
165
|
+
- lib/assets/javascripts/autocomplete-rails.js
|
166
|
+
- lib/cucumber/autocomplete.rb
|
167
|
+
- lib/generators/autocomplete/install_generator.rb
|
168
|
+
- lib/generators/autocomplete/uncompressed_generator.rb
|
169
|
+
- lib/rails3-jquery-autocomplete/autocomplete.rb
|
170
|
+
- lib/rails3-jquery-autocomplete/formtastic.rb
|
171
|
+
- lib/rails3-jquery-autocomplete/formtastic_plugin.rb
|
172
|
+
- lib/rails3-jquery-autocomplete/form_helper.rb
|
173
|
+
- lib/rails3-jquery-autocomplete/orm/active_record.rb
|
174
|
+
- lib/rails3-jquery-autocomplete/orm/mongoid.rb
|
175
|
+
- lib/rails3-jquery-autocomplete/orm/mongo_mapper.rb
|
176
|
+
- lib/rails3-jquery-autocomplete/orm.rb
|
177
|
+
- lib/rails3-jquery-autocomplete/rails/engine.rb
|
178
|
+
- lib/rails3-jquery-autocomplete/simple_form_plugin.rb
|
179
|
+
- lib/rails3-jquery-autocomplete/version.rb
|
180
|
+
- lib/rails3-jquery-autocomplete.rb
|
181
|
+
- lib/steak/autocomplete.rb
|
182
|
+
- CHANGELOG.md
|
183
|
+
- LICENSE
|
184
|
+
- README.md
|
185
|
+
- Rakefile
|
186
|
+
homepage: http://github.com/crowdint/rails3-jquery-autocomplete
|
187
|
+
licenses: []
|
188
|
+
post_install_message:
|
189
|
+
rdoc_options: []
|
190
|
+
require_paths:
|
191
|
+
- lib
|
192
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
193
|
+
none: false
|
194
|
+
requirements:
|
195
|
+
- - ! '>='
|
196
|
+
- !ruby/object:Gem::Version
|
197
|
+
version: '0'
|
198
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
199
|
+
none: false
|
200
|
+
requirements:
|
201
|
+
- - ! '>='
|
202
|
+
- !ruby/object:Gem::Version
|
203
|
+
version: '0'
|
204
|
+
requirements: []
|
205
|
+
rubyforge_project:
|
206
|
+
rubygems_version: 1.8.24
|
207
|
+
signing_key:
|
208
|
+
specification_version: 3
|
209
|
+
summary: Use jQuery's autocomplete plugin with Rails 3.
|
210
|
+
test_files: []
|