rails3-jquery-autocomplete 0.8.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +1 -0
- data/README.markdown +11 -2
- data/Rakefile +8 -0
- data/integration/app/views/id_elements/new.html.haml +1 -1
- data/integration/public/javascripts/autocomplete-rails.js +2 -99
- data/lib/generators/templates/autocomplete-rails-uncompressed.js +4 -4
- data/lib/generators/templates/autocomplete-rails.js +2 -2
- data/lib/rails3-jquery-autocomplete.rb +7 -6
- data/lib/rails3-jquery-autocomplete/autocomplete.rb +87 -41
- 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 +30 -0
- data/lib/rails3-jquery-autocomplete/version.rb +1 -1
- data/rails3-jquery-autocomplete.gemspec +2 -1
- data/test/generators/autocomplete/install_generator_test.rb +1 -1
- data/test/generators/autocomplete/uncompressed_generator_test.rb +2 -2
- data/test/lib/rails3-jquery-autocomplete/autocomplete_test.rb +59 -0
- data/test/lib/rails3-jquery-autocomplete/orm/active_record_test.rb +130 -0
- data/test/lib/rails3-jquery-autocomplete/orm/mongo_mapper_test.rb +60 -0
- data/test/lib/rails3-jquery-autocomplete/orm/mongoid_test.rb +60 -0
- data/test/lib/rails3-jquery-autocomplete_test.rb +38 -0
- data/test/test_helper.rb +5 -2
- metadata +56 -41
- data/lib/rails3-jquery-autocomplete/helpers.rb +0 -137
- data/test/implementations_test.rb +0 -41
- data/test/lib/rails3-jquery-autocomplete/helpers_test.rb +0 -16
- data/test/support/active_record.rb +0 -44
- data/test/support/mongo_mapper.rb +0 -39
- data/test/support/mongoid.rb +0 -43
- data/test/test_controller.rb +0 -101
data/CHANGELOG.md
CHANGED
data/README.markdown
CHANGED
@@ -146,7 +146,7 @@ This options receives a method name as the parameter, and that method will be ca
|
|
146
146
|
|
147
147
|
In the example above, you will search by _name_, but the autocomplete list will display the result of _funky_method_
|
148
148
|
|
149
|
-
This wouldn't really make much sense unless you use it with the
|
149
|
+
This wouldn't really make much sense unless you use it with the "id_element" attribute. (See below)
|
150
150
|
|
151
151
|
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
|
152
152
|
|
@@ -159,6 +159,15 @@ Only the object's id and the column you are searching on will be returned in JSO
|
|
159
159
|
By default autocomplete uses method name as column name. Now it can be specified using column_name options
|
160
160
|
`:column_name => 'name'`
|
161
161
|
|
162
|
+
#### json encoder
|
163
|
+
Autocomplete uses Yajl as JSON encoder/decoder, but you can specify your own
|
164
|
+
|
165
|
+
class ProductsController < Admin::BaseController
|
166
|
+
autocomplete :brand, :name do |items|
|
167
|
+
CustomJSON::Encoder.encode(items)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
162
171
|
### View
|
163
172
|
|
164
173
|
On your view, all you have to do is include the attribute autocomplete on the text field
|
@@ -183,7 +192,7 @@ Now your autocomplete code is unobtrusive, Rails 3 style.
|
|
183
192
|
|
184
193
|
### Getting the object id
|
185
194
|
|
186
|
-
If you need to use the id of the selected object, you can use the
|
195
|
+
If you need to use the id of the selected object, you can use the *id_element* attribute too:
|
187
196
|
|
188
197
|
f.autocomplete_field :brand_name, autocomplete_brand_name_products_path, :id_element => '#some_element'
|
189
198
|
|
data/Rakefile
CHANGED
@@ -2,6 +2,7 @@ require 'bundler'
|
|
2
2
|
Bundler::GemHelper.install_tasks
|
3
3
|
|
4
4
|
require 'rake/testtask'
|
5
|
+
require 'rcov/rcovtask'
|
5
6
|
|
6
7
|
task :default => [:uglify, :test]
|
7
8
|
|
@@ -18,3 +19,10 @@ task :uglify do
|
|
18
19
|
f << Uglifier.compile(File.read("#{file_folder}/autocomplete-rails-uncompressed.js"))
|
19
20
|
end
|
20
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
|
@@ -6,7 +6,7 @@
|
|
6
6
|
= form.text_field :name
|
7
7
|
%p
|
8
8
|
= form.label :brand_name
|
9
|
-
= form.autocomplete_field :brand_name, autocomplete_brand_name_id_elements_path,
|
9
|
+
= form.autocomplete_field :brand_name, autocomplete_brand_name_id_elements_path, 'data-id-element' => '#product_brand_id'
|
10
10
|
%p
|
11
11
|
= form.label :brand_id
|
12
12
|
= form.text_field :brand_id
|
@@ -11,103 +11,6 @@
|
|
11
11
|
* be updated with the element id whenever you find a matching value
|
12
12
|
*
|
13
13
|
* Example:
|
14
|
-
* <input type="text" data-autocomplete="/url/to/autocomplete"
|
14
|
+
* <input type="text" data-autocomplete="/url/to/autocomplete" data-id-element="#id_field">
|
15
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('id_element')) {
|
89
|
-
$($(this).attr('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('id_element')).val("");
|
103
|
-
$(this).unbind('keyup.clearId');
|
104
|
-
}
|
105
|
-
});
|
106
|
-
$(this).trigger('railsAutocomplete.select');
|
107
|
-
|
108
|
-
return false;
|
109
|
-
}
|
110
|
-
});
|
111
|
-
}
|
112
|
-
});
|
113
|
-
})(jQuery);
|
16
|
+
$(document).ready(function(){$("input[data-autocomplete]").railsAutocomplete()}),function(a){var b=null;a.fn.railsAutocomplete=function(){return this.live("focus",function(){this.railsAutoCompleter||(this.railsAutoCompleter=new a.railsAutocomplete(this))})},a.railsAutocomplete=function(a){_e=a,this.init(_e)},a.railsAutocomplete.fn=a.railsAutocomplete.prototype={railsAutocomplete:"0.0.1"},a.railsAutocomplete.fn.extend=a.railsAutocomplete.extend=a.extend,a.railsAutocomplete.fn.extend({init:function(a){function c(a){return b(a).pop().replace(/^\s+/,"")}function b(b){return b.split(a.delimiter)}a.delimiter=$(a).attr("data-delimiter")||null,$(a).autocomplete({source:function(b,d){$.getJSON($(a).attr("data-autocomplete"),{term:c(b.term)},function(){$(arguments[0]).each(function(b,c){var d={};d[c.id]=c,$(a).data(d)}),d.apply(null,arguments)})},search:function(){var a=c(this.value);if(a.length<2)return!1},focus:function(){return!1},select:function(c,d){var f=b(this.value);f.pop(),f.push(d.item.value);if(a.delimiter!=null)f.push(""),this.value=f.join(a.delimiter);else{this.value=f.join(""),$(this).attr("data-id-element")&&$($(this).attr("data-id-element")).val(d.item.id);if($(this).attr("data-update-elements")){var g=$(this).data(d.item.id.toString()),h=$.parseJSON($(this).attr("data-update-elements"));for(var i in h)$(h[i]).val(g[i])}}var j=this.value;$(this).bind("keyup.clearId",function(){$(this).val().trim()!=j.trim()&&($($(this).attr("data-id-element")).val(""),$(this).unbind("keyup.clearId"))}),$(this).trigger("railsAutocomplete.select");return!1}})}})}(jQuery)
|
@@ -11,7 +11,7 @@
|
|
11
11
|
* be updated with the element id whenever you find a matching value
|
12
12
|
*
|
13
13
|
* Example:
|
14
|
-
* <input type="text" data-autocomplete="/url/to/autocomplete"
|
14
|
+
* <input type="text" data-autocomplete="/url/to/autocomplete" data-id-element="#id_field">
|
15
15
|
*/
|
16
16
|
|
17
17
|
$(document).ready(function(){
|
@@ -85,8 +85,8 @@ $(document).ready(function(){
|
|
85
85
|
this.value = terms.join( e.delimiter );
|
86
86
|
} else {
|
87
87
|
this.value = terms.join("");
|
88
|
-
if ($(this).attr('
|
89
|
-
$($(this).attr('
|
88
|
+
if ($(this).attr('data-id-element')) {
|
89
|
+
$($(this).attr('data-id-element')).val(ui.item.id);
|
90
90
|
}
|
91
91
|
if ($(this).attr('data-update-elements')) {
|
92
92
|
var data = $(this).data(ui.item.id.toString());
|
@@ -99,7 +99,7 @@ $(document).ready(function(){
|
|
99
99
|
var remember_string = this.value;
|
100
100
|
$(this).bind('keyup.clearId', function(){
|
101
101
|
if($(this).val().trim() != remember_string.trim()){
|
102
|
-
$($(this).attr('
|
102
|
+
$($(this).attr('data-id-element')).val("");
|
103
103
|
$(this).unbind('keyup.clearId');
|
104
104
|
}
|
105
105
|
});
|
@@ -11,6 +11,6 @@
|
|
11
11
|
* be updated with the element id whenever you find a matching value
|
12
12
|
*
|
13
13
|
* Example:
|
14
|
-
* <input type="text" data-autocomplete="/url/to/autocomplete"
|
14
|
+
* <input type="text" data-autocomplete="/url/to/autocomplete" data-id-element="#id_field">
|
15
15
|
*/
|
16
|
-
$(document).ready(function(){$("input[data-autocomplete]").railsAutocomplete()}),function(a){var b=null;a.fn.railsAutocomplete=function(){return this.live("focus",function(){this.railsAutoCompleter||(this.railsAutoCompleter=new a.railsAutocomplete(this))})},a.railsAutocomplete=function(a){_e=a,this.init(_e)},a.railsAutocomplete.fn=a.railsAutocomplete.prototype={railsAutocomplete:"0.0.1"},a.railsAutocomplete.fn.extend=a.railsAutocomplete.extend=a.extend,a.railsAutocomplete.fn.extend({init:function(a){function c(a){return b(a).pop().replace(/^\s+/,"")}function b(b){return b.split(a.delimiter)}a.delimiter=$(a).attr("data-delimiter")||null,$(a).autocomplete({source:function(b,d){$.getJSON($(a).attr("data-autocomplete"),{term:c(b.term)},function(){$(arguments[0]).each(function(b,c){var d={};d[c.id]=c,$(a).data(d)}),d.apply(null,arguments)})},search:function(){var a=c(this.value);if(a.length<2)return!1},focus:function(){return!1},select:function(c,d){var f=b(this.value);f.pop(),f.push(d.item.value);if(a.delimiter!=null)f.push(""),this.value=f.join(a.delimiter);else{this.value=f.join(""),$(this).attr("
|
16
|
+
$(document).ready(function(){$("input[data-autocomplete]").railsAutocomplete()}),function(a){var b=null;a.fn.railsAutocomplete=function(){return this.live("focus",function(){this.railsAutoCompleter||(this.railsAutoCompleter=new a.railsAutocomplete(this))})},a.railsAutocomplete=function(a){_e=a,this.init(_e)},a.railsAutocomplete.fn=a.railsAutocomplete.prototype={railsAutocomplete:"0.0.1"},a.railsAutocomplete.fn.extend=a.railsAutocomplete.extend=a.extend,a.railsAutocomplete.fn.extend({init:function(a){function c(a){return b(a).pop().replace(/^\s+/,"")}function b(b){return b.split(a.delimiter)}a.delimiter=$(a).attr("data-delimiter")||null,$(a).autocomplete({source:function(b,d){$.getJSON($(a).attr("data-autocomplete"),{term:c(b.term)},function(){$(arguments[0]).each(function(b,c){var d={};d[c.id]=c,$(a).data(d)}),d.apply(null,arguments)})},search:function(){var a=c(this.value);if(a.length<2)return!1},focus:function(){return!1},select:function(c,d){var f=b(this.value);f.pop(),f.push(d.item.value);if(a.delimiter!=null)f.push(""),this.value=f.join(a.delimiter);else{this.value=f.join(""),$(this).attr("data-id-element")&&$($(this).attr("data-id-element")).val(d.item.id);if($(this).attr("data-update-elements")){var g=$(this).data(d.item.id.toString()),h=$.parseJSON($(this).attr("data-update-elements"));for(var i in h)$(h[i]).val(g[i])}}var j=this.value;$(this).bind("keyup.clearId",function(){$(this).val().trim()!=j.trim()&&($($(this).attr("data-id-element")).val(""),$(this).unbind("keyup.clearId"))}),$(this).trigger("railsAutocomplete.select");return!1}})}})}(jQuery)
|
@@ -1,17 +1,18 @@
|
|
1
|
-
require 'yajl/json_gem'
|
2
1
|
require 'rails3-jquery-autocomplete/form_helper'
|
3
|
-
require 'rails3-jquery-autocomplete/helpers'
|
4
2
|
require 'rails3-jquery-autocomplete/autocomplete'
|
5
|
-
|
3
|
+
|
4
|
+
module Rails3JQueryAutocomplete
|
5
|
+
autoload :Orm , 'rails3-jquery-autocomplete/orm'
|
6
|
+
autoload :FormtasticPlugin , 'rails3-jquery-autocomplete/formtastic_plugin'
|
7
|
+
end
|
6
8
|
|
7
9
|
class ActionController::Base
|
8
|
-
|
9
|
-
include Rails3JQueryAutocomplete::Helpers
|
10
|
+
include Rails3JQueryAutocomplete::Autocomplete
|
10
11
|
end
|
11
12
|
|
12
13
|
#
|
13
14
|
# Load the formtastic plugin if using Formtastic
|
14
|
-
#
|
15
|
+
# TODO: Better way to load plugins
|
15
16
|
begin
|
16
17
|
require 'formtastic'
|
17
18
|
class Formtastic::SemanticFormBuilder < ActionView::Helpers::FormBuilder
|
@@ -1,50 +1,96 @@
|
|
1
|
-
require "yajl"
|
2
|
-
|
3
1
|
module Rails3JQueryAutocomplete
|
2
|
+
module Autocomplete
|
3
|
+
def self.included(target)
|
4
|
+
target.extend Rails3JQueryAutocomplete::Autocomplete::ClassMethods
|
5
|
+
|
6
|
+
if defined?(Mongoid::Document)
|
7
|
+
target.send :include, Rails3JQueryAutocomplete::Orm::Mongoid
|
8
|
+
elsif defined?(MongoMapper::Document)
|
9
|
+
target.send :include, Rails3JQueryAutocomplete::Orm::MongoMapper
|
10
|
+
else
|
11
|
+
target.send :include, Rails3JQueryAutocomplete::Orm::ActiveRecord
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
#
|
16
|
+
# Usage:
|
17
|
+
#
|
18
|
+
# class ProductsController < Admin::BaseController
|
19
|
+
# autocomplete :brand, :name
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# This will magically generate an action autocomplete_brand_name, so,
|
23
|
+
# don't forget to add it on your routes file
|
24
|
+
#
|
25
|
+
# resources :products do
|
26
|
+
# get :autocomplete_brand_name, :on => :collection
|
27
|
+
# end
|
28
|
+
#
|
29
|
+
# Now, on your view, all you have to do is have a text field like:
|
30
|
+
#
|
31
|
+
# f.text_field :brand_name, :autocomplete => autocomplete_brand_name_products_path
|
32
|
+
#
|
33
|
+
#
|
34
|
+
# Yajl is used by default to encode results, if you want to use a different encoder
|
35
|
+
# you can specify your custom encoder via block
|
36
|
+
#
|
37
|
+
# class ProductsController < Admin::BaseController
|
38
|
+
# autocomplete :brand, :name do |items|
|
39
|
+
# CustomJSONEncoder.encode(items)
|
40
|
+
# end
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
module ClassMethods
|
44
|
+
def autocomplete(object, method, options = {})
|
45
|
+
define_method("autocomplete_#{object}_#{method}") do
|
46
|
+
|
47
|
+
method = options[:column_name] if options.has_key?(:column_name)
|
48
|
+
|
49
|
+
term = params[:term]
|
50
|
+
|
51
|
+
if term && !term.blank?
|
52
|
+
#allow specifying fully qualified class name for model object
|
53
|
+
class_name = options[:class_name] || object
|
54
|
+
items = get_autocomplete_items(:model => get_object(class_name), \
|
55
|
+
:options => options, :term => term, :method => method)
|
56
|
+
else
|
57
|
+
items = {}
|
58
|
+
end
|
4
59
|
|
5
|
-
|
6
|
-
#
|
7
|
-
# Usage:
|
8
|
-
#
|
9
|
-
# class ProductsController < Admin::BaseController
|
10
|
-
# autocomplete :brand, :name
|
11
|
-
# end
|
12
|
-
#
|
13
|
-
# This will magically generate an action autocomplete_brand_name, so,
|
14
|
-
# don't forget to add it on your routes file
|
15
|
-
#
|
16
|
-
# resources :products do
|
17
|
-
# get :autocomplete_brand_name, :on => :collection
|
18
|
-
# end
|
19
|
-
#
|
20
|
-
# Now, on your view, all you have to do is have a text field like:
|
21
|
-
#
|
22
|
-
# f.text_field :brand_name, :autocomplete => autocomplete_brand_name_products_path
|
23
|
-
#
|
24
|
-
#
|
25
|
-
module ClassMethods
|
26
|
-
def autocomplete(object, method, options = {})
|
27
|
-
|
28
|
-
define_method("autocomplete_#{object}_#{method}") do
|
29
|
-
|
30
|
-
|
31
|
-
method = options[:column_name] if options.has_key?(:column_name)
|
32
|
-
|
33
|
-
term = params[:term]
|
34
|
-
|
35
|
-
if term && !term.empty?
|
36
|
-
#allow specifying fully qualified class name for model object
|
37
|
-
class_name = options[:class_name] || object
|
38
|
-
items = get_autocomplete_items(:model => get_object(class_name), \
|
39
|
-
:options => options, :term => term, :method => method)
|
40
|
-
else
|
41
|
-
items = {}
|
60
|
+
render :json => json_for_autocomplete(items, options[:display_value] ||= method, options[:extra_data])
|
42
61
|
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Returns a limit that will be used on the query
|
66
|
+
def get_autocomplete_limit(options)
|
67
|
+
options[:limit] ||= 10
|
68
|
+
end
|
43
69
|
|
44
|
-
|
70
|
+
# Returns parameter model_sym as a constant
|
71
|
+
#
|
72
|
+
# get_object(:actor)
|
73
|
+
# # returns a Actor constant supposing it is already defined
|
74
|
+
#
|
75
|
+
def get_object(model_sym)
|
76
|
+
object = model_sym.to_s.camelize.constantize
|
77
|
+
end
|
78
|
+
|
79
|
+
#
|
80
|
+
# Returns a hash with three keys actually used by the Autocomplete jQuery-ui
|
81
|
+
# Can be overriden to show whatever you like
|
82
|
+
# Hash also includes a key/value pair for each method in extra_data
|
83
|
+
#
|
84
|
+
def json_for_autocomplete(items, method, extra_data=[])
|
85
|
+
items.collect do |item|
|
86
|
+
hash = {"id" => item.id.to_s, "label" => item.send(method), "value" => item.send(method)}
|
87
|
+
extra_data.each do |datum|
|
88
|
+
hash[datum] = item.send(datum)
|
89
|
+
end if extra_data
|
90
|
+
# TODO: Come back to remove this if clause when test suite is better
|
91
|
+
hash
|
45
92
|
end
|
46
93
|
end
|
47
94
|
end
|
48
|
-
|
49
95
|
end
|
50
96
|
|
@@ -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 get_autocomplete_order(method, options, model=nil)
|
5
|
+
order = options[:order]
|
6
|
+
|
7
|
+
table_prefix = model ? "#{model.table_name}." : ""
|
8
|
+
order || "#{table_prefix}#{method} ASC"
|
9
|
+
end
|
10
|
+
|
11
|
+
def get_autocomplete_items(parameters)
|
12
|
+
model = parameters[:model]
|
13
|
+
term = parameters[:term]
|
14
|
+
method = parameters[:method]
|
15
|
+
options = parameters[:options]
|
16
|
+
scopes = Array(options[:scopes])
|
17
|
+
limit = get_autocomplete_limit(options)
|
18
|
+
order = get_autocomplete_order(method, options, model)
|
19
|
+
|
20
|
+
|
21
|
+
items = model.scoped
|
22
|
+
|
23
|
+
scopes.each { |scope| items = items.send(scope) } unless scopes.empty?
|
24
|
+
|
25
|
+
items = items.select(get_autocomplete_select_clause(model, method, options)) unless options[:full_model]
|
26
|
+
items = items.where(get_autocomplete_where_clause(model, term, method, options)).
|
27
|
+
limit(limit).order(order)
|
28
|
+
end
|
29
|
+
|
30
|
+
def get_autocomplete_select_clause(model, method, options)
|
31
|
+
table_name = model.table_name
|
32
|
+
(["#{table_name}.#{model.primary_key}", "#{table_name}.#{method}"] + (options[:extra_data].blank? ? [] : options[:extra_data]))
|
33
|
+
end
|
34
|
+
|
35
|
+
def get_autocomplete_where_clause(model, term, method, options)
|
36
|
+
table_name = model.table_name
|
37
|
+
is_full_search = options[:full]
|
38
|
+
like_clause = (postgres? ? 'ILIKE' : 'LIKE')
|
39
|
+
["LOWER(#{table_name}.#{method}) #{like_clause} ?", "#{(is_full_search ? '%' : '')}#{term.downcase}%"]
|
40
|
+
end
|
41
|
+
|
42
|
+
def postgres?
|
43
|
+
defined?(PGConn)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Rails3JQueryAutocomplete
|
2
|
+
module Orm
|
3
|
+
module MongoMapper
|
4
|
+
def get_autocomplete_order(method, options, model=nil)
|
5
|
+
order = options[:order]
|
6
|
+
if order
|
7
|
+
order.split(',').collect do |fields|
|
8
|
+
sfields = fields.split
|
9
|
+
[sfields[0].downcase.to_sym, sfields[1].downcase.to_sym]
|
10
|
+
end
|
11
|
+
else
|
12
|
+
[[method.to_sym, :asc]]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def get_autocomplete_items(parameters)
|
17
|
+
model = parameters[:model]
|
18
|
+
method = parameters[:method]
|
19
|
+
options = parameters[:options]
|
20
|
+
is_full_search = options[:full]
|
21
|
+
term = parameters[:term]
|
22
|
+
limit = get_autocomplete_limit(options)
|
23
|
+
order = get_autocomplete_order(method, options)
|
24
|
+
|
25
|
+
search = (is_full_search ? '.*' : '^') + term + '.*'
|
26
|
+
items = model.where(method.to_sym => /#{search}/i).limit(limit).sort(order)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|