rails3-jquery-autocomplete 0.8.0 → 0.9.0
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 +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
|