autocomplete-activeadmin 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,44 @@
1
+ module AutocompleteActiveAdmin
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 AutocompleteActiveAdmin
2
+ module Orm
3
+ autoload :ActiveRecord , 'autocomplete-activeadmin/orm/active_record'
4
+ autoload :Mongoid , 'autocomplete-activeadmin/orm/mongoid'
5
+ autoload :MongoMapper , 'autocomplete-activeadmin/orm/mongo_mapper'
6
+ end
7
+ end
8
+
@@ -0,0 +1,83 @@
1
+ module AutocompleteActiveAdmin
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
+ if sqlite?
9
+ order || "LOWER(#{method}) ASC"
10
+ else
11
+ order || "LOWER(#{table_prefix}#{method}) ASC"
12
+ end
13
+ end
14
+
15
+ def active_record_get_autocomplete_items(parameters)
16
+ model = parameters[:model]
17
+ term = parameters[:term]
18
+ options = parameters[:options]
19
+ method = options[:hstore] ? options[:hstore][:method] : parameters[:method]
20
+ scopes = Array(options[:scopes])
21
+ where = options[:where]
22
+ limit = get_autocomplete_limit(options)
23
+ order = active_record_get_autocomplete_order(method, options, model)
24
+
25
+ items = (::Rails::VERSION::MAJOR * 10 + ::Rails::VERSION::MINOR) >= 40 ? model.where(nil) : model.scoped
26
+
27
+ scopes.each { |scope| items = items.send(scope) } unless scopes.empty?
28
+
29
+ items = items.select(get_autocomplete_select_clause(model, method, options)) unless options[:full_model]
30
+ items = items.where(get_autocomplete_where_clause(model, term, method, options)).
31
+ limit(limit).order(order)
32
+ items = items.where(where) unless where.blank?
33
+
34
+ items
35
+ end
36
+
37
+ def get_autocomplete_select_clause(model, method, options)
38
+ if sqlite?
39
+ table_name = model.quoted_table_name
40
+ ([
41
+ "#{table_name}.#{model.connection.quote_column_name(model.primary_key)} as #{model.primary_key}",
42
+ "#{table_name}.#{model.connection.quote_column_name(method)} as #{method}"
43
+ ] + (options[:extra_data].blank? ? [] : options[:extra_data]))
44
+ else
45
+ table_name = model.table_name
46
+ (["#{table_name}.#{model.primary_key}", "#{table_name}.#{method}"] + (options[:extra_data].blank? ? [] : options[:extra_data]))
47
+ end
48
+ end
49
+
50
+ def get_autocomplete_where_clause(model, term, method, options)
51
+ table_name = model.table_name
52
+ is_full_search = options[:full]
53
+ is_case_sensitive_search = options[:case_sensitive]
54
+ like_clause = (postgres?(model) && !is_case_sensitive_search ? 'ILIKE' : 'LIKE')
55
+ column_transform = is_case_sensitive_search ? '' : 'LOWER'
56
+ term = "#{(is_full_search ? '%' : '')}#{term.gsub(/([_%\\])/, '\\\\\1')}%"
57
+ if options[:hstore]
58
+ ["#{column_transform}(#{table_name}.#{method} -> '#{options[:hstore][:key]}') LIKE #{column_transform}(?)", term]
59
+ elsif sqlite?
60
+ ["#{column_transform}(#{method}) #{like_clause} #{column_transform}(?)", term]
61
+ else
62
+ ["#{column_transform}(#{table_name}.#{method}) #{like_clause} #{column_transform}(?)", term]
63
+ end
64
+ end
65
+
66
+ protected
67
+
68
+ def sqlite?
69
+ begin
70
+ return ::ActiveRecord::Base.connection.to_s.match(/SQLite/)
71
+ rescue ::ActiveRecord::ConnectionNotEstablished
72
+ return false
73
+ end
74
+ return false
75
+ end
76
+
77
+ def postgres?(model)
78
+ # Figure out if this particular model uses the PostgreSQL adapter
79
+ model.connection.class.to_s.match(/PostgreSQLAdapter/)
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,32 @@
1
+ module AutocompleteActiveAdmin
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
+ is_case_sensitive_search = options[:case_sensitive]
22
+ term = parameters[:term]
23
+ limit = get_autocomplete_limit(options)
24
+ order = mongo_mapper_get_autocomplete_order(method, options)
25
+
26
+ search = (is_full_search ? '.*' : '^') + term + '.*'
27
+ search = Regexp.new(search, !is_case_sensitive_search)
28
+ items = model.where(method.to_sym => search).limit(limit).sort(order)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,36 @@
1
+ module AutocompleteActiveAdmin
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
+ is_case_sensitive_search = options[:case_sensitive]
22
+ term = parameters[:term]
23
+ limit = get_autocomplete_limit(options)
24
+ order = mongoid_get_autocomplete_order(method, options)
25
+
26
+ if is_full_search
27
+ search = '.*' + Regexp.escape(term) + '.*'
28
+ else
29
+ search = '^' + Regexp.escape(term)
30
+ end
31
+ search = Regexp.new(search, !is_case_sensitive_search)
32
+ items = model.where(method.to_sym => search).limit(limit).order_by(order)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,5 @@
1
+ module AutocompleteActiveAdmin
2
+ module Rails
3
+ class Engine < ::Rails::Engine ; end
4
+ end
5
+ end
@@ -0,0 +1,100 @@
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-autocomplete-fields"] = JSON.generate(options.delete :fields) if options[:fields]
11
+ new_options["data-update-elements"] = JSON.generate(options.delete :update_elements) if options[:update_elements]
12
+ new_options["data-id-element"] = options.delete :id_element if options[:id_element]
13
+ input_html_options.merge new_options
14
+ end
15
+ end
16
+
17
+ class AutocompleteInput < Base
18
+ include Autocomplete
19
+
20
+ protected
21
+ def limit
22
+ column && column.limit
23
+ end
24
+
25
+ def has_placeholder?
26
+ placeholder_present?
27
+ end
28
+
29
+ def input(args = nil)
30
+ # This branching is to deal with a change beginning in simple_form 3.0.2 and above to ensure backwards compatibility
31
+ if args.nil?
32
+ @builder.autocomplete_field(
33
+ attribute_name,
34
+ options[:url],
35
+ rewrite_autocomplete_option
36
+ )
37
+ else
38
+ @builder.autocomplete_field(
39
+ attribute_name,
40
+ options[:url],
41
+ merge_wrapper_options(rewrite_autocomplete_option, args)
42
+ )
43
+ end
44
+ end
45
+ end
46
+
47
+ class AutocompleteCollectionInput < CollectionInput
48
+ include Autocomplete
49
+
50
+ def input(opts)
51
+ # http://www.codeofficer.com/blog/entry/form_builders_in_rails_discovering_field_names_and_ids_for_javascript/
52
+ hidden_id = "#{object_name}_#{attribute_name}_hidden".gsub(/\]\[|[^-a-zA-Z0-9:.]/, "_").sub(/_$/, "")
53
+ id_element = options[:id_element]
54
+ if id_element
55
+ id_element << ", #" << hidden_id
56
+ else
57
+ id_element = "#" + hidden_id
58
+ end
59
+ options[:id_element] = id_element
60
+
61
+ # This branching is to deal with a change beginning in simple_form 3.0.2 and above to ensure backwards compatibility
62
+ if opts.nil?
63
+ autocomplete_options = rewrite_autocomplete_option
64
+ else
65
+ merge_wrapper_options(rewrite_autocomplete_option, args)
66
+ end
67
+
68
+ label_method, value_method = detect_collection_methods
69
+ association = object.send(reflection.name)
70
+ if association && association.respond_to?(label_method)
71
+ autocomplete_options[:value] = association.send(label_method)
72
+ end
73
+ out = @builder.autocomplete_field(
74
+ attribute_name,
75
+ options[:url],
76
+ autocomplete_options
77
+ )
78
+ hidden_options = if association && association.respond_to?(value_method)
79
+ new_options = {}
80
+ new_options[:value] = association.send(value_method)
81
+ input_html_options.merge new_options
82
+ else
83
+ input_html_options
84
+ end
85
+ hidden_options[:id] = hidden_id
86
+ out << @builder.hidden_field(
87
+ attribute_name,
88
+ hidden_options
89
+ )
90
+ out.html_safe
91
+ end
92
+ end
93
+ end
94
+
95
+ class FormBuilder
96
+ map_type :autocomplete, :to => SimpleForm::Inputs::AutocompleteInput
97
+ map_type :autocomplete_collection, :to => SimpleForm::Inputs::AutocompleteCollectionInput
98
+ end
99
+
100
+ end
@@ -0,0 +1,3 @@
1
+ module AutocompleteActiveAdmin
2
+ VERSION = '0.1.0'
3
+ end
@@ -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,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,247 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: autocomplete-activeadmin
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Juan Grados
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-04-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '3.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '3.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: sqlite3-ruby
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: mongoid
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: 2.0.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 2.0.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: mongo_mapper
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0.9'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0.9'
69
+ - !ruby/object:Gem::Dependency
70
+ name: bson_ext
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 1.6.2
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 1.6.2
83
+ - !ruby/object:Gem::Dependency
84
+ name: guard
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: guard-test
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: test-unit
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 2.2.0
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 2.2.0
125
+ - !ruby/object:Gem::Dependency
126
+ name: shoulda
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: 3.0.1
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: 3.0.1
139
+ - !ruby/object:Gem::Dependency
140
+ name: uglifier
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: rr
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: simple_form
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: '1.5'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: '1.5'
181
+ - !ruby/object:Gem::Dependency
182
+ name: byebug
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
195
+ description: Use jQuery's autocomplete plugin with Rails 4+.
196
+ email: juaninf@gmail.com
197
+ executables: []
198
+ extensions: []
199
+ extra_rdoc_files: []
200
+ files:
201
+ - CHANGELOG.md
202
+ - LICENSE
203
+ - README.md
204
+ - Rakefile
205
+ - lib/assets/javascripts/autocomplete-rails-uncompressed.js
206
+ - lib/assets/javascripts/autocomplete-rails.js
207
+ - lib/autocomplete-activeadmin.rb
208
+ - lib/autocomplete-activeadmin/autocomplete.rb
209
+ - lib/autocomplete-activeadmin/form_helper.rb
210
+ - lib/autocomplete-activeadmin/formtastic.rb
211
+ - lib/autocomplete-activeadmin/formtastic_plugin.rb
212
+ - lib/autocomplete-activeadmin/orm.rb
213
+ - lib/autocomplete-activeadmin/orm/active_record.rb
214
+ - lib/autocomplete-activeadmin/orm/mongo_mapper.rb
215
+ - lib/autocomplete-activeadmin/orm/mongoid.rb
216
+ - lib/autocomplete-activeadmin/rails/engine.rb
217
+ - lib/autocomplete-activeadmin/simple_form_plugin.rb
218
+ - lib/autocomplete-activeadmin/version.rb
219
+ - lib/cucumber/autocomplete.rb
220
+ - lib/generators/autocomplete/install_generator.rb
221
+ - lib/generators/autocomplete/uncompressed_generator.rb
222
+ - lib/steak/autocomplete.rb
223
+ homepage: http://juaninf.blogspot.com
224
+ licenses:
225
+ - MIT
226
+ metadata: {}
227
+ post_install_message:
228
+ rdoc_options: []
229
+ require_paths:
230
+ - lib
231
+ required_ruby_version: !ruby/object:Gem::Requirement
232
+ requirements:
233
+ - - ">="
234
+ - !ruby/object:Gem::Version
235
+ version: '0'
236
+ required_rubygems_version: !ruby/object:Gem::Requirement
237
+ requirements:
238
+ - - ">="
239
+ - !ruby/object:Gem::Version
240
+ version: '0'
241
+ requirements: []
242
+ rubyforge_project:
243
+ rubygems_version: 2.6.11
244
+ signing_key:
245
+ specification_version: 4
246
+ summary: Use jQuery's autocomplete plugin with Rails 4+.
247
+ test_files: []