wf-rails3-jquery-autocomplete 1.0.4
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.
- 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: []
|