rails4-autocomplete 1.0.7
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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +31 -0
- data/README.md +374 -0
- data/Rakefile +21 -0
- data/lib/assets/javascripts/autocomplete-rails-uncompressed.js +136 -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/rails4-autocomplete.rb +23 -0
- data/lib/rails4-autocomplete/autocomplete.rb +96 -0
- data/lib/rails4-autocomplete/form_helper.rb +47 -0
- data/lib/rails4-autocomplete/formtastic.rb +41 -0
- data/lib/rails4-autocomplete/formtastic_plugin.rb +44 -0
- data/lib/rails4-autocomplete/orm.rb +8 -0
- data/lib/rails4-autocomplete/orm/active_record.rb +52 -0
- data/lib/rails4-autocomplete/orm/mongo_mapper.rb +30 -0
- data/lib/rails4-autocomplete/orm/mongoid.rb +34 -0
- data/lib/rails4-autocomplete/rails/engine.rb +5 -0
- data/lib/rails4-autocomplete/simple_form_plugin.rb +84 -0
- data/lib/rails4-autocomplete/version.rb +3 -0
- data/lib/steak/autocomplete.rb +12 -0
- data/test/form_helper_test.rb +25 -0
- data/test/generators/autocomplete/install_generator_test.rb +25 -0
- data/test/generators/autocomplete/uncompressed_generator_test.rb +25 -0
- data/test/lib/rails3-jquery-autocomplete/autocomplete_test.rb +59 -0
- data/test/lib/rails3-jquery-autocomplete/orm/active_record_test.rb +145 -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/simple_form_plugin_test.rb +33 -0
- data/test/lib/rails3-jquery-autocomplete_test.rb +38 -0
- data/test/test_helper.rb +36 -0
- data/test/view_test_helper.rb +108 -0
- metadata +268 -0
@@ -0,0 +1,84 @@
|
|
1
|
+
module SimpleForm
|
2
|
+
module Inputs
|
3
|
+
module Autocomplete
|
4
|
+
#
|
5
|
+
# Method used to rename the autocomplete key to a more standard
|
6
|
+
# data-autocomplete key
|
7
|
+
#
|
8
|
+
def rewrite_autocomplete_option
|
9
|
+
new_options = {}
|
10
|
+
new_options["data-update-elements"] = JSON.generate(options.delete :update_elements) if options[:update_elements]
|
11
|
+
new_options["data-id-element"] = options.delete :id_element if options[:id_element]
|
12
|
+
input_html_options.merge new_options
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class AutocompleteInput < Base
|
17
|
+
include Autocomplete
|
18
|
+
|
19
|
+
def input
|
20
|
+
@builder.autocomplete_field(
|
21
|
+
attribute_name,
|
22
|
+
options[:url],
|
23
|
+
rewrite_autocomplete_option
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
protected
|
28
|
+
def limit
|
29
|
+
column && column.limit
|
30
|
+
end
|
31
|
+
|
32
|
+
def has_placeholder?
|
33
|
+
placeholder_present?
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class AutocompleteCollectionInput < CollectionInput
|
38
|
+
include Autocomplete
|
39
|
+
|
40
|
+
def input
|
41
|
+
# http://www.codeofficer.com/blog/entry/form_builders_in_rails_discovering_field_names_and_ids_for_javascript/
|
42
|
+
hidden_id = "#{object_name}_#{attribute_name}_hidden".gsub(/\]\[|[^-a-zA-Z0-9:.]/, "_").sub(/_$/, "")
|
43
|
+
id_element = options[:id_element]
|
44
|
+
if id_element
|
45
|
+
id_element << ", #" << hidden_id
|
46
|
+
else
|
47
|
+
id_element = "#" + hidden_id
|
48
|
+
end
|
49
|
+
options[:id_element] = id_element
|
50
|
+
autocomplete_options = rewrite_autocomplete_option
|
51
|
+
#
|
52
|
+
label_method, value_method = detect_collection_methods
|
53
|
+
association = object.send(reflection.name)
|
54
|
+
if association && association.respond_to?(label_method)
|
55
|
+
autocomplete_options[:value] = association.send(label_method)
|
56
|
+
end
|
57
|
+
out = @builder.autocomplete_field(
|
58
|
+
attribute_name,
|
59
|
+
options[:url],
|
60
|
+
autocomplete_options
|
61
|
+
)
|
62
|
+
hidden_options = if association && association.respond_to?(value_method)
|
63
|
+
new_options = {}
|
64
|
+
new_options[:value] = association.send(value_method)
|
65
|
+
input_html_options.merge new_options
|
66
|
+
else
|
67
|
+
input_html_options
|
68
|
+
end
|
69
|
+
hidden_options[:id] = hidden_id
|
70
|
+
out << @builder.hidden_field(
|
71
|
+
attribute_name,
|
72
|
+
hidden_options
|
73
|
+
)
|
74
|
+
out.html_safe
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
class FormBuilder
|
80
|
+
map_type :autocomplete, :to => SimpleForm::Inputs::AutocompleteInput
|
81
|
+
map_type :autocomplete_collection, :to => SimpleForm::Inputs::AutocompleteCollectionInput
|
82
|
+
end
|
83
|
+
|
84
|
+
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
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class Post
|
4
|
+
attr_accessor :author
|
5
|
+
end
|
6
|
+
|
7
|
+
class FormHelperTest < ActionView::TestCase
|
8
|
+
def test_text_field_tag
|
9
|
+
assert_match(/autocomplete=\"some\/path\"/, text_field_tag('field_name', '', :autocomplete => 'some/path'))
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_text_field
|
13
|
+
post = Post.new
|
14
|
+
assert_match(/autocomplete=\"some\/path\"/, text_field(:post, :author, :autocomplete => 'some/path'))
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_autocomplete_field_tag
|
18
|
+
assert_match(/data-autocomplete=\"some\/path\"/, autocomplete_field_tag('field_name', '', 'some/path'))
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_autocomplete_field
|
22
|
+
post= Post.new
|
23
|
+
assert_match(/data-autocomplete=\"some\/path\"/, autocomplete_field(:post, :author, 'some/path'))
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'generators/autocomplete/install_generator'
|
3
|
+
|
4
|
+
module Autocomplete
|
5
|
+
class InstallGeneratorTest < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
@destination = File.join('tmp', 'test_app')
|
8
|
+
@source = InstallGenerator.source_root
|
9
|
+
@filename = File.join(@destination, 'public', 'javascripts', 'autocomplete-rails.js')
|
10
|
+
|
11
|
+
File.unlink(@filename) if File.exists?(@filename)
|
12
|
+
|
13
|
+
InstallGenerator.start([], :destination_root => @destination)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_install
|
17
|
+
assert File.exists?(@filename)
|
18
|
+
|
19
|
+
assert_equal(
|
20
|
+
File.read(File.join(@source, 'autocomplete-rails.js')),
|
21
|
+
File.read(@filename)
|
22
|
+
)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'generators/autocomplete/uncompressed_generator'
|
3
|
+
|
4
|
+
module Autocomplete
|
5
|
+
class UncompressedGeneratorTest < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
@destination = File.join('tmp', 'test_app')
|
8
|
+
@source = UncompressedGenerator.source_root
|
9
|
+
@filename = File.join(@destination, 'public', 'javascripts', 'autocomplete-rails.js')
|
10
|
+
|
11
|
+
File.unlink(@filename) if File.exists?(@filename)
|
12
|
+
|
13
|
+
UncompressedGenerator.start([], :destination_root => @destination)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_install
|
17
|
+
assert File.exists?(@filename)
|
18
|
+
|
19
|
+
assert_equal(
|
20
|
+
File.read(File.join(@source, 'autocomplete-rails-uncompressed.js')),
|
21
|
+
File.read(@filename)
|
22
|
+
)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Rails4Autocomplete
|
4
|
+
class AutocompleteTest < Test::Unit::TestCase
|
5
|
+
include Rails4Autocomplete::Autocomplete
|
6
|
+
|
7
|
+
context '#get_autocomplete_limit' do
|
8
|
+
context 'the limit option was specified' do
|
9
|
+
should "return the limit option" do
|
10
|
+
assert_equal 99, get_autocomplete_limit({:limit => 99})
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'the limit option is not specified' do
|
15
|
+
should 'return 10' do
|
16
|
+
assert_equal 10, get_autocomplete_limit({})
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context '#get_object' do
|
22
|
+
should 'return the specified sym as a class name' do
|
23
|
+
symbol = Object.new
|
24
|
+
class_object = Class.new
|
25
|
+
mock(symbol).to_s.mock!.camelize.mock!.constantize { class_object }
|
26
|
+
assert_equal class_object, get_object(symbol)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context '#json_for_autocomplete' do
|
31
|
+
should 'parse items to JSON' do
|
32
|
+
item = mock(Object)
|
33
|
+
mock(item).send(:name).times(2) { 'Object Name' }
|
34
|
+
mock(item).id { 1 }
|
35
|
+
items = [item]
|
36
|
+
response = self.json_for_autocomplete(items, :name).first
|
37
|
+
assert_equal response["id"], "1"
|
38
|
+
assert_equal response["value"], "Object Name"
|
39
|
+
assert_equal response["label"], "Object Name"
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'with extra data' do
|
43
|
+
should 'add that extra data to result' do
|
44
|
+
item = mock(Object)
|
45
|
+
mock(item).send(:name).times(2) { 'Object Name' }
|
46
|
+
mock(item).id { 1 }
|
47
|
+
mock(item).send("extra") { 'Object Extra ' }
|
48
|
+
|
49
|
+
items = [item]
|
50
|
+
response = self.json_for_autocomplete(items, :name, ["extra"]).first
|
51
|
+
|
52
|
+
assert_equal "1" , response["id"]
|
53
|
+
assert_equal "Object Name" , response["value"]
|
54
|
+
assert_equal "Object Name" , response["label"]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,145 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Rails4Autocomplete
|
4
|
+
module Orm
|
5
|
+
class ActiveRecordTest < Test::Unit::TestCase
|
6
|
+
include Rails4Autocomplete::Orm::ActiveRecord
|
7
|
+
|
8
|
+
context "#get_autocomplete_order" do
|
9
|
+
context 'order is specified' do
|
10
|
+
should 'returns that order option' do
|
11
|
+
assert_equal "field ASC", get_autocomplete_order(:field, {:order => 'field ASC'})
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'no order is specified' do
|
16
|
+
should 'return the order clause by the field ASC' do
|
17
|
+
assert_equal "field ASC", get_autocomplete_order(:field, {})
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'a different model is specified' do
|
21
|
+
should 'return the order clause by the table_name.field ASC' do
|
22
|
+
model = Object.new
|
23
|
+
mock(model).table_name { 'table_name' }
|
24
|
+
assert_equal "table_name.field ASC", get_autocomplete_order(:field, {}, model)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context '#get_autocomplete_items' do
|
31
|
+
should 'retrieve the items from ActiveRecord' do
|
32
|
+
class Dog ; end
|
33
|
+
|
34
|
+
model = Dog
|
35
|
+
scoped = []
|
36
|
+
whered = []
|
37
|
+
term = 'query'
|
38
|
+
method = :field
|
39
|
+
|
40
|
+
options = {
|
41
|
+
:model => model,
|
42
|
+
:term => term,
|
43
|
+
:method => method,
|
44
|
+
:options => {}
|
45
|
+
}
|
46
|
+
|
47
|
+
mock(self).get_autocomplete_limit(anything) { 10 }
|
48
|
+
mock(self).get_autocomplete_order(anything, anything, anything) { "order ASC" }
|
49
|
+
mock(self).get_autocomplete_select_clause(model, method, {}) { ["field"] }
|
50
|
+
mock(self).get_autocomplete_where_clause(model, term, method, {}) { ["WHERE something"] }
|
51
|
+
mock(model).table_name.times(any_times) { 'model_table_name' }
|
52
|
+
|
53
|
+
mock(model).scoped { model }
|
54
|
+
mock(model).select(["field"]) { model }
|
55
|
+
mock(model).where(["WHERE something"]).mock!.limit(10).mock!.
|
56
|
+
order("order ASC") { 1 }
|
57
|
+
|
58
|
+
assert_equal 1, get_autocomplete_items(options)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context '#get_autocomplete_select_clause' do
|
63
|
+
setup do
|
64
|
+
@model = Object.new
|
65
|
+
mock(@model).table_name { 'table_name' }
|
66
|
+
mock(@model).primary_key { 'id' }
|
67
|
+
end
|
68
|
+
|
69
|
+
should 'create a select clause' do
|
70
|
+
assert_equal ["table_name.id", "table_name.method"],
|
71
|
+
get_autocomplete_select_clause(@model, :method, {})
|
72
|
+
end
|
73
|
+
|
74
|
+
context 'with extra options' do
|
75
|
+
should 'return those extra fields on the clause' do
|
76
|
+
options = {:extra_data => ['table_name.created_at']}
|
77
|
+
|
78
|
+
assert_equal ["table_name.id", "table_name.method", "table_name.created_at"],
|
79
|
+
get_autocomplete_select_clause(@model, :method, options)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context '#get_autocomplete_where_clause' do
|
85
|
+
setup do
|
86
|
+
@model = Object.new
|
87
|
+
mock(@model).table_name { 'table_name' }
|
88
|
+
|
89
|
+
@term = 'query'
|
90
|
+
@options = {}
|
91
|
+
@method = :method
|
92
|
+
end
|
93
|
+
|
94
|
+
context 'Not Postgres' do
|
95
|
+
should 'return options for where' do
|
96
|
+
mock(self).postgres?(@model) { false }
|
97
|
+
assert_equal ["LOWER(table_name.method) LIKE ?", "query%"], get_autocomplete_where_clause(@model, @term, @method, @options)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context 'Postgres' do
|
102
|
+
should 'return options for where with ILIKE' do
|
103
|
+
mock(self).postgres?(@model) { true }
|
104
|
+
assert_equal ["LOWER(table_name.method) ILIKE ?", "query%"], get_autocomplete_where_clause(@model, @term, @method, @options)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
context 'full search' do
|
109
|
+
should 'return options for where with the term sourrounded by %%' do
|
110
|
+
mock(self).postgres?(@model) { false }
|
111
|
+
@options[:full] = true
|
112
|
+
assert_equal ["LOWER(table_name.method) LIKE ?", "%query%"], get_autocomplete_where_clause(@model, @term, @method, @options)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
context '#postgres?' do
|
118
|
+
setup do
|
119
|
+
@model = stub
|
120
|
+
end
|
121
|
+
|
122
|
+
context 'the connection class is not postgres' do
|
123
|
+
setup do
|
124
|
+
mock(@model).connection { stub }
|
125
|
+
end
|
126
|
+
|
127
|
+
should 'return nil if the connection class matches PostgreSQLAdapter' do
|
128
|
+
assert_nil self.postgres?(@model)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
context 'the connection class matches PostgreSQLAdapter' do
|
133
|
+
setup do
|
134
|
+
class PostgreSQLAdapter; end
|
135
|
+
mock(@model).connection { PostgreSQLAdapter.new }
|
136
|
+
end
|
137
|
+
|
138
|
+
should 'return true' do
|
139
|
+
assert self.postgres?(@model)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Rails4Autocomplete
|
4
|
+
module Orm
|
5
|
+
class MongoMapperTest < Test::Unit::TestCase
|
6
|
+
include Rails4Autocomplete::Orm::MongoMapper
|
7
|
+
|
8
|
+
context "#get_autocomplete_order" do
|
9
|
+
context "order is specified" do
|
10
|
+
should 'returns the parametrized order for Mongoid' do
|
11
|
+
assert_equal [[:field, :asc], [:state, :desc]],
|
12
|
+
get_autocomplete_order(:method, :order => 'field ASC, state DESC')
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'order is not specified' do
|
17
|
+
should 'return the method ordered ASC by default' do
|
18
|
+
assert_equal [[:method, :asc]],
|
19
|
+
get_autocomplete_order(:method, {})
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "#get_autocomplete_items" do
|
25
|
+
setup do
|
26
|
+
@model = mock(Object)
|
27
|
+
|
28
|
+
@parameters = {
|
29
|
+
:model => @model,
|
30
|
+
:method => :field,
|
31
|
+
:term => 'query',
|
32
|
+
:options => {:full => false}
|
33
|
+
}
|
34
|
+
mock(self).get_autocomplete_limit(anything) { 10 }
|
35
|
+
mock(self).get_autocomplete_order(anything, anything) { [[:order, :asc]] }
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'not a full search' do
|
39
|
+
should 'do stuff' do
|
40
|
+
mock(@model).where({:field=>/^query.*/i}).mock!.limit(10).
|
41
|
+
mock!.sort([[:order, :asc]])
|
42
|
+
|
43
|
+
get_autocomplete_items(@parameters)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'full search' do
|
48
|
+
should 'return a full search query' do
|
49
|
+
@parameters[:options] = {:full => true}
|
50
|
+
|
51
|
+
mock(@model).where({:field => /.*query.*/i}).mock!.limit(10).
|
52
|
+
mock!.sort([[:order, :asc]])
|
53
|
+
|
54
|
+
get_autocomplete_items(@parameters)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|