autocomplete 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 [name of plugin creator]
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.
@@ -0,0 +1,16 @@
1
+ MIT-LICENSE
2
+ README.rdoc
3
+ Rakefile
4
+ assets/autocomplete-loading.gif
5
+ assets/autocomplete.css
6
+ assets/autocomplete.js
7
+ autocomplete.gemspec
8
+ id_rsa.pub
9
+ init.rb
10
+ install.rb
11
+ lib/autocomplete.rb
12
+ lib/autocomplete_controller.rb
13
+ lib/autocomplete_helper.rb
14
+ tasks/autocomplete_tasks.rake
15
+ test/autocomplete_test.rb
16
+ Manifest
@@ -0,0 +1,10 @@
1
+ Autocomplete
2
+ ============
3
+ Introduction goes here.
4
+
5
+ Example
6
+ =======
7
+ Example goes here.
8
+
9
+
10
+ Copyright (c) 2010 [name of plugin creator], released under the MIT license
@@ -0,0 +1,14 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require "echoe"
4
+
5
+ Echoe.new('autocomplete', '1.0.1') do |p|
6
+ p.description = "Insert an autocomplete-search-box inside your view"
7
+ p.url = "http://www.voja-jovanovic.info"
8
+ p.author = "Voislav Jovanovic"
9
+ p.email = "voislavj@gmail.com"
10
+ p.ignore_pattern = ["tmp/*", "script/*"]
11
+ p.development_dependencies = []
12
+ end
13
+
14
+ Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each {|ext| load ext}
@@ -0,0 +1,74 @@
1
+ .autocomplete-loading {
2
+ background-image:url(/images/autocomplete-loading.gif);
3
+ background-repeat: no-repeat;
4
+ background-position: 98% center;
5
+ }
6
+ .autocomplete-multi-controls .autocomplete-remove {
7
+ float:right;
8
+ margin-bottom:5px;
9
+ }
10
+ .autocomplete-multi-controls a {
11
+ outline:none;
12
+ }
13
+ .autocomplete-multi-container {
14
+ width:200px;
15
+ clear:both;
16
+ border:1px solid #ccc;
17
+ overflow:auto;
18
+ }
19
+ .autocomplete-multi-rowset {
20
+ padding:2px 4px;
21
+ border-bottom:1px dotted #ddd;
22
+ cursor:default;
23
+ }
24
+ .autocomplete-multi-rowset:hover {
25
+ background-color:#E8730C;
26
+ color:#fff;
27
+ }
28
+ .autocomplete-multi-rowset.selected,
29
+ .autocomplete-multi-rowset.selected:hover {
30
+ background:#eee;color:#000
31
+ }
32
+ .autocomplete-multi-rowset label{margin-left:5px;}
33
+ .autocomplete-multi-rowset:hover label{color:#fff}
34
+ .autocomplete-multi-rowset.selected:hover label{color:#000}
35
+
36
+ .autocomplete-list {
37
+ list-style-type:none;
38
+ position:absolute;
39
+ background:#fff;
40
+ border:1px solid #ccc;
41
+ width:300px;
42
+ max-height:200px;
43
+ overflow:auto;
44
+ }
45
+ .autocomplete-list li{
46
+ margin:0;
47
+ padding:0;
48
+ }
49
+ .autocomplete-list li.empty{
50
+ padding:2px 4px;
51
+ color:#777;
52
+ }
53
+ .autocomplete-list li.odd {
54
+ background:#eee;
55
+ }
56
+ .autocomplete-list a {
57
+ display:block;
58
+ text-decoration:none;
59
+ padding:2px 4px;
60
+ outline:none;
61
+ }
62
+ .autocomplete-list a:focus,
63
+ .autocomplete-list a:hover {
64
+ background:Highlight;
65
+ color:HighlightText;
66
+ }
67
+ .autocomplete-multi-status {
68
+ width:192px;
69
+ background:#ccc;
70
+ font-size:10px;
71
+ color:#555;
72
+ padding:2px 5px;
73
+ text-align:right;
74
+ }
@@ -0,0 +1,320 @@
1
+ /**
2
+ * @author Voislav Voja Jovanovic
3
+ * @version 1.0.0
4
+ */
5
+
6
+
7
+ function Autocomplete(element, options) {
8
+
9
+ // if autocomplete is already initialized, just return
10
+ if(element.hasAttribute("ready")) {
11
+ return;
12
+ }
13
+ element.writeAttribute("ready", "ready");
14
+
15
+ // patch element's name if `multi` is on
16
+ if(options["multi"] && !options["name"].match(/\[\]$/)) {
17
+ options["name"] += "[]";
18
+ }
19
+
20
+ // Attach Events
21
+ document.body.observe("click", function(){
22
+ Autocomplete_RemoveList(element);
23
+ });
24
+
25
+ element.adjacent(".autocomplete-multi-controls").each(function(ctrl){
26
+ ctrl.select(".autocomplete-select-all")[0].observe("click", function(){
27
+ Autocomplete_getCheckboxes(element).each(function(cb){
28
+ cb.checked = true;
29
+ cb.parentNode.addClassName("selected");
30
+ });
31
+ });
32
+ ctrl.select(".autocomplete-select-none")[0].observe("click", function(){
33
+ Autocomplete_getCheckboxes(element).each(function(cb){
34
+ cb.checked = false;
35
+ cb.parentNode.removeClassName("selected");
36
+ });
37
+ });
38
+ ctrl.select(".autocomplete-remove")[0].observe("click",function(){
39
+ var rows = Autocomplete_getCheckedRows(element);
40
+ if(rows.length>0) {
41
+ if(confirm("You are about to remove " + rows.length + " item(s).\nDo you want to proceed?")) {
42
+ rows.each(function(r){r.remove();})
43
+ Autocomplete_UpdateStatus(element);
44
+ }
45
+ }
46
+ });
47
+ });
48
+
49
+ element.observe("keyup", function(e){
50
+ var el = e.target;
51
+
52
+ // special keys
53
+ switch(e.keyCode) {
54
+
55
+ case 27: // Esc
56
+ Autocomplete_RemoveList(el);
57
+
58
+ case 40: // Arrow Down
59
+ // focus into list
60
+ el.adjacent("ul.autocomplete-list li:first-child a").each(function(a){
61
+ a.focus();
62
+ a.select();
63
+ });
64
+
65
+ case 9: // Tab
66
+ case 13: // Enter
67
+ case 17: // Ctrl
68
+ case 18: // Alt
69
+ case 19: // Pause/Break
70
+ case 20: // Caps Lock
71
+ case 33: // PageUp
72
+ case 34: // PageDown
73
+ case 35: // End
74
+ case 36: // Home
75
+ case 37: // Arrow Left
76
+ case 38: // Arrow Up
77
+ case 39: // Arrow Right
78
+ case 44: // PrintScreen
79
+ case 45: // Insert
80
+ case 92: // Win
81
+ case 93: // Context
82
+ // do nothing
83
+ return;
84
+ break;
85
+ }
86
+
87
+ Autocomplete_Stop(el);
88
+
89
+ el.timeout = setTimeout(function(){
90
+ // check keyword length
91
+ el.value = el.value.replace(/^[\s\r\n\t]+|[\s\r\n\t]+$/g, "")
92
+ if(el.value.length<3) return;
93
+
94
+ // build POST params
95
+ var data = "";
96
+ if (typeof(options.glue) != "undefined") {
97
+ data += "&glue="+escape(options.glue);
98
+ }
99
+ if(typeof(options.map) != "undefined") {
100
+ if(typeof(options.map.value) != "object") {
101
+ options.map.value = [options.map.value];
102
+ }
103
+ for(var i=0; i<options.map.value.length; i++) {
104
+ data += "&map[value][]=" + options.map.value[i];
105
+ }
106
+ if(typeof(options.map.label) != "object") {
107
+ options.map.label = [options.map.label];
108
+ }
109
+ for(var i=0; i<options.map.label.length; i++) {
110
+ data += "&map[label][]=" + options.map.label[i];
111
+ }
112
+ for(var i=0; i<options.map.search.length; i++) {
113
+ data += "&map[search][]=" + options.map.search[i];
114
+ }
115
+ for(var i=0; i<options.joins.length; i++) {
116
+ data += "&joins[]=" + options.joins[i];
117
+ }
118
+ }
119
+ if (options["multi"]) {
120
+ el.next(".autocomplete-multi-container").select("input[type=checkbox]").each(function(e){
121
+ data += "&skip[]=" + e.value
122
+ });
123
+ }
124
+
125
+ // remove previous list if there's one
126
+ Autocomplete_RemoveList(el);
127
+
128
+ // reset hidden input before sending new request
129
+ if(!options["multi"]) {
130
+ el.parentNode.select("input[type=hidden]").first().value = "";
131
+ }
132
+
133
+ // make Request
134
+ new Ajax.Request("/autocomplete/find/" + options.model + "/" + _esc(el.value), {
135
+ method: "post",
136
+ parameters: data.substr(1),
137
+ onCreate: function(){
138
+ el.addClassName("autocomplete-loading");
139
+ },
140
+ onComplete: function(req){
141
+ el.removeClassName("autocomplete-loading");
142
+ if(req.status==200) {
143
+ var response = eval('(' + req.responseText + ')');
144
+
145
+ var ul = new Element("ul", {
146
+ "class": "autocomplete-list"
147
+ });
148
+ var position = el.positionedOffset()
149
+ ul.setStyle({
150
+ left: position[0] + "px",
151
+ top: position[1] + el.getHeight() + "px"
152
+ });
153
+ el.insert({
154
+ before: ul
155
+ });
156
+ if (response.length > 0) {
157
+ var li, a, rem;
158
+ for (var i = 0; i < response.length; i++) {
159
+ // list-item
160
+ li = new Element("li");
161
+ if (i % 2) {
162
+ li.addClassName("odd");
163
+ }
164
+ // item-value
165
+ a = new Element("a");
166
+ a.href = "javascript:void(0);";
167
+ a.r = response[i];
168
+
169
+ a.observe("keyup", function(e){
170
+ switch(e.keyCode) {
171
+ case 27: // Esc
172
+ Autocomplete_RemoveList(el);
173
+ break;
174
+ case 40: // Arrow Down
175
+ this.parentNode.next("li").select("a")[0].focus();
176
+ break;
177
+ case 38: // Arrow Up
178
+ this.parentNode.previous("li").select("a")[0].focus();
179
+ break;
180
+ }
181
+ });
182
+
183
+ a.observe("click", function(e){
184
+ var next = this.parentNode.previous("li");
185
+ if(next) {
186
+ next = next.select("a")[0];
187
+ }else{
188
+ next = this.parentNode.next("li");
189
+ if(next) {
190
+ next = next.select("a")[0];
191
+ }
192
+ }
193
+ if (options["multi"]) {
194
+ var c = el.next(".autocomplete-multi-container");
195
+ if (c.select("div.ac-" + this.r["value"]).length == 0) {
196
+ span = new Element("div", {
197
+ "class": "autocomplete-multi-rowset ac-" + this.r["value"]
198
+ });
199
+ span.observe("click", function(e){
200
+ var chk = this.select("input[type=checkbox]")[0];
201
+ if(e.target.hasClassName("autocomplete-multi-rowset")) {
202
+ chk.checked = chk.checked?false:true;
203
+ }
204
+ if(chk.checked) {
205
+ this.addClassName("selected");
206
+ }else{
207
+ this.removeClassName("selected");
208
+ }
209
+ });
210
+ var id = "ac_input_" + this.r["value"];
211
+ inpt = new Element("input", {
212
+ "type": "checkbox",
213
+ "name": options["name"],
214
+ "id": id,
215
+ "value": this.r["value"]
216
+ });
217
+ span.insert(inpt);
218
+
219
+ label = new Element("label", {"for":id}).update(this.r["label"]);
220
+ span.insert(label)
221
+
222
+ c.insert(span);
223
+
224
+ if (this.parentNode.parentNode.select("li").length == 1) {
225
+ Autocomplete_RemoveList(el);
226
+ }
227
+ else {
228
+ this.parentNode.remove();
229
+ }
230
+ Autocomplete_UpdateStatus(el);
231
+ }
232
+ Event.stop(e);
233
+ }
234
+ else {
235
+ el.value = this.r["label"];
236
+ el.title = "value: " + this.r["value"];
237
+ el.parentNode.select("input[type=hidden]").first().value = this.r["value"];
238
+ }
239
+
240
+ // focus to previous
241
+ if(next) next.focus()
242
+ });
243
+ a.innerHTML = response[i]["label"];
244
+ li.insert(a);
245
+
246
+ ul.insert(li);
247
+ }
248
+ }else{
249
+ var empty = new Element("li", {"class": "empty"}).update("No results.");
250
+ ul.insert(empty);
251
+ setTimeout(function(){
252
+ Autocomplete_RemoveList(el);
253
+ }, 2000);
254
+ }
255
+ }else{
256
+ //alert(req.status + ". " + req.statusText);
257
+ }
258
+ }
259
+ });
260
+
261
+ }, 800);
262
+
263
+ });
264
+ element.observe("keypress", function(e){
265
+ Autocomplete_Stop(e.target);
266
+ });
267
+
268
+
269
+ }
270
+ function Autocomplete_Stop(element) {
271
+ var to = element.timeout;
272
+ if(to) {
273
+ clearTimeout(to);
274
+ element.timeout = null;
275
+ }
276
+ }
277
+ function Autocomplete_RemoveList(element) {
278
+ var list = $$(".autocomplete-list");
279
+ list.each(function(el){el.remove();});
280
+ element.focus();
281
+ }
282
+ function Autocomplete_UpdateStatus(element) {
283
+ var container = element.next(".autocomplete-multi-container");
284
+ if (container) {
285
+ element.next(".autocomplete-multi-status").select(".length").each(function(s){
286
+ s.innerHTML = container.select(".autocomplete-multi-rowset").length+"";
287
+ });
288
+ }
289
+
290
+ }
291
+ function Autocomplete_getCheckboxes(element) {
292
+ ret = [];
293
+ element.adjacent(".autocomplete-multi-container")[0].select("input[type=checkbox]").each(function(cb){
294
+ ret.push(cb);
295
+ });
296
+ return ret;
297
+ }
298
+ function Autocomplete_getCheckedRows(element) {
299
+ ret = [];
300
+ element.adjacent(".autocomplete-multi-container")[0].select("input[type=checkbox]").each(function(cb){
301
+ if(cb.checked) {
302
+ ret.push(cb.parentNode);
303
+ }
304
+ });
305
+ return ret;
306
+ }
307
+
308
+ function _esc(str) {
309
+ str = str + ""
310
+ var ret = "", c;
311
+ for(var i=0; i<str.length; i++) {
312
+ c = str[i];
313
+ if(!c.match(/[a-z0-9]/i)) {
314
+ c = c.charCodeAt(0);
315
+ c = "%" + c.toString(16);
316
+ }
317
+ ret += c;
318
+ }
319
+ return ret;
320
+ }
@@ -0,0 +1,31 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{autocomplete}
5
+ s.version = "1.0.1"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Voislav Jovanovic"]
9
+ s.date = %q{2010-07-23}
10
+ s.description = %q{Insert an autocomplete-search-box inside your view}
11
+ s.email = %q{voislavj@gmail.com}
12
+ s.extra_rdoc_files = ["README.rdoc", "lib/autocomplete.rb", "lib/autocomplete_controller.rb", "lib/autocomplete_helper.rb", "tasks/autocomplete_tasks.rake"]
13
+ s.files = ["MIT-LICENSE", "README.rdoc", "Rakefile", "assets/autocomplete-loading.gif", "assets/autocomplete.css", "assets/autocomplete.js", "autocomplete.gemspec", "id_rsa.pub", "init.rb", "install.rb", "lib/autocomplete.rb", "lib/autocomplete_controller.rb", "lib/autocomplete_helper.rb", "tasks/autocomplete_tasks.rake", "test/autocomplete_test.rb", "Manifest"]
14
+ s.homepage = %q{http://www.voja-jovanovic.info}
15
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Autocomplete", "--main", "README.rdoc"]
16
+ s.require_paths = ["lib"]
17
+ s.rubyforge_project = %q{autocomplete}
18
+ s.rubygems_version = %q{1.3.7}
19
+ s.summary = %q{Insert an autocomplete-search-box inside your view}
20
+ s.test_files = ["test/autocomplete_test.rb"]
21
+
22
+ if s.respond_to? :specification_version then
23
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
24
+ s.specification_version = 3
25
+
26
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
27
+ else
28
+ end
29
+ else
30
+ end
31
+ end
@@ -0,0 +1 @@
1
+ ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAxm7FhP0LM71UVtxZLiZdmx0cyzj2cNCqE4UOD+JF5HvkbAmv2ySIqyO4NMSq9Ww96P+GW8o6UlnhzhziNMRoeon2b59AsjV5d8q8rlOKGT5z7zkN8VpoT8iht+wpQrZX4SLshlmwR90nP4ygDWh9Z9wZ1GVje36GqVUdYAKh0c2zYH5MZrfEuTIIMzaMJm6faRE/MG1Gx/Lqo+0mGw6k1Uz4Y7j8M/rm+SDC6Ws0TotKnnHkvhT2ZDi8ZB0Qvf7Zz0U/oamKYArXeLAeR6U+ytNozXq9lWvB15wKzLFYEHJonpmh3IH2oazfvksE1nzBlMGF37oHTJCDZ/hsQ+yAiQ== User@VOJA
data/init.rb ADDED
@@ -0,0 +1,5 @@
1
+ # Include hook code here
2
+ require 'autocomplete_controller'
3
+ require 'autocomplete_helper'
4
+
5
+ ActionView::Base.send(:include, AutocompleteHelper)
@@ -0,0 +1,10 @@
1
+ # Install hook code here
2
+ #require 'ftools'
3
+ #
4
+ #plugins_dir = File.expand_path(".")
5
+ #autocomplete_dir = File.join(plugins_dir, 'autocomplete')
6
+ #root_dir = File.join(autocomplete_dir, '..', '..', '..')
7
+ #
8
+ #File.copy File.join(autocomplete_dir, 'assets', 'autocomplete.js'), File.join(root_dir, 'public', 'javascripts', 'autocomplete.js')
9
+ #File.copy File.join(autocomplete_dir, 'assets', 'autocomplete.css'), File.join(root_dir, 'public', 'stylesheets', 'autocomplete.css')
10
+ #File.copy File.join(autocomplete_dir, 'assets', 'autocomplete-loading.gif'), File.join(root_dir, 'public', 'images', 'autocomplete-loading.gif')
@@ -0,0 +1,9 @@
1
+ # Autocomplete
2
+ %w{ models controllers }.each do |dir|
3
+ path = File.join(File.dirname(__FILE__), 'app', dir)
4
+ $LOAD_PATH << path
5
+ ActiveSupport::Dependencies.load_paths << path
6
+ ActiveSupport::Dependencies.load_once_paths.delete(path)
7
+ end
8
+
9
+ require "autocomplete/routing"
@@ -0,0 +1,78 @@
1
+ class AutocompleteController < ActionController::Base
2
+
3
+ def find
4
+ params[:map] = {:value=>[:id], :label=>[:name], :search=>[:name]} unless params[:map]
5
+ params[:limit] ||= 50
6
+ params[:skip] ||= []
7
+ params[:map][:search] ||= []
8
+ params[:glue] ||= " "
9
+
10
+ params[:joins] ||= []
11
+
12
+ @modelname = params[:model]
13
+ @model = params[:model].constantize
14
+
15
+ params[:map][:label] = parse_table_fields(params[:map][:label])
16
+ params[:map][:value] = parse_table_fields(params[:map][:value])
17
+ params[:map][:search] = parse_table_fields(params[:map][:search])
18
+
19
+ params[:joins].each_with_index do |v,k|
20
+ params[:joins][k] = eval(":#{v}")
21
+ end
22
+
23
+ value = "CONCAT_WS(' ',#{params[:map][:value].join(",")})"
24
+ label = "CONCAT_WS('#{params[:glue]}',#{params[:map][:label].join(",")})"
25
+ search = "CONCAT_WS(' ',#{(params[:map][:label]|params[:map][:search]).join(",")})"
26
+
27
+ skip = ""
28
+ toskip = ""
29
+
30
+ params[:skip].each do |s|
31
+ toskip += ","
32
+ unless s.to_s.match(/^\d+$/i)
33
+ s = "'#{s}'"
34
+ end
35
+ toskip += s
36
+ end
37
+
38
+ toskip = toskip.gsub(/^,/, "")
39
+ if params[:skip].length>0
40
+ skip = "AND #{value} NOT IN(#{toskip})"
41
+ end
42
+
43
+ debug params[:joins]
44
+
45
+ result = @model.find(
46
+ :all, {
47
+ :select => "#{value} as `value`, #{label} as `label`",
48
+ :conditions => ["#{search} LIKE ? #{skip}", "%" + params[:keyword].gsub("%", "\%") + "%"],
49
+ :joins => params[:joins],
50
+ :order => "label",
51
+ :limit => params[:limit]
52
+ }
53
+ );
54
+ render :text => result.to_json
55
+ end
56
+
57
+ def debug(var, mode="w")
58
+ File.open("D:\\voja.log", mode) {|f| f.write(var.to_yaml); f.close}
59
+ end
60
+
61
+ def parse_table_fields(arr)
62
+ single = false
63
+ unless arr.is_a?(Array)
64
+ arr = [arr]
65
+ single = true
66
+ end
67
+
68
+ arr.each_with_index do |v,k|
69
+ puts v.inspect + " => " + v.to_s.inspect
70
+ if v.to_s.match(/\./)
71
+ items = v.to_s.split(".",2)
72
+ arr[k] = "#{items[0].constantize.table_name}.#{items[1]}"
73
+ end
74
+ end
75
+ return single ? arr[0] : arr;
76
+ end
77
+
78
+ end
@@ -0,0 +1,43 @@
1
+ module AutocompleteHelper
2
+
3
+ # generate autocomplete text-field
4
+ def autocomplete(options={})
5
+ return nil unless options[:model]
6
+
7
+ options[:name] ||= :autocomplete_keyword
8
+ options[:multi] ||= false;
9
+
10
+ options[:multi_height] ||= 150
11
+ options[:uuid] = _uuid
12
+
13
+ options[:map][:value] ||= :id
14
+ options[:map][:label] ||= [:name]
15
+ options[:map][:search] ||= []
16
+
17
+ #txt_name = options[:multi] ? "autocomplete-keyword-#{options[:uuid]}" : options[:name]
18
+ txt_name = "autocomplete-keyword-#{options[:uuid]}"
19
+
20
+ ret = []
21
+ ret << javascript_include_tag("autocomplete")
22
+ ret << stylesheet_link_tag("autocomplete")
23
+ ret << label_tag(txt_name, options[:model].camelize)
24
+ ret << text_field_tag(txt_name, nil, {
25
+ :onfocus => "Autocomplete(this, " + options.to_json.to_s + ")"
26
+ })
27
+
28
+ if options[:multi]
29
+ ret << content_tag(:div, '<a class="autocomplete-remove" href="javascript:void(0);">remove selected</a> select <a href="javascript:void(0)" class="autocomplete-select-all">all</a> / <a href="javascript:void(0)" class="autocomplete-select-none">none</a>', :class=>"autocomplete-multi-controls")
30
+ ret << content_tag(:div, "", :class=>"autocomplete-multi-container", :style=>"height: #{options[:multi_height]}px")
31
+ ret << content_tag(:div, "<span class=\"length\">0</span> items", :class=>"autocomplete-multi-status")
32
+ else
33
+ ret << hidden_field_tag(options[:name], "")
34
+ end
35
+
36
+ return ret.join("\r\n")
37
+ end
38
+
39
+ def _uuid
40
+ o = [('a'..'z'),('A'..'Z'),(0..9)].map{|i| i.to_a}.flatten;
41
+ string = (0..10).map{ o[rand(o.length)] }.join;
42
+ end
43
+ end
@@ -0,0 +1,15 @@
1
+ # desc "Explaining what the task does"
2
+ # task :autocomplete do
3
+ # # Task goes here
4
+ # end
5
+ desc 'Update autocomplete JavaScripts and CSSs'
6
+ task :update_scripts => [] do |t|
7
+
8
+ autocomplete_dir = File.expand_path(".")
9
+ [["javascripts","autocomplete.js"], ["stylesheets","autocomplete.css"]].each do |file|
10
+ unless File.exists?(File.join(RAILS_ROOT, "public", file[0], file[1]))
11
+ File.copy(File.join("assets", file[1]), File.join(RAILS_ROOT, "public", file[0], file[1]))
12
+ end
13
+ end
14
+ puts "JavaScripts and CSSs updated."
15
+ end
@@ -0,0 +1,8 @@
1
+ require 'test/unit'
2
+
3
+ class AutocompleteTest < Test::Unit::TestCase
4
+ # Replace this with your real tests.
5
+ def test_this_plugin
6
+ flunk
7
+ end
8
+ end
metadata ADDED
@@ -0,0 +1,92 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: autocomplete
3
+ version: !ruby/object:Gem::Version
4
+ hash: 21
5
+ prerelease: false
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 1
10
+ version: 1.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Voislav Jovanovic
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-07-23 00:00:00 +02:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: Insert an autocomplete-search-box inside your view
23
+ email: voislavj@gmail.com
24
+ executables: []
25
+
26
+ extensions: []
27
+
28
+ extra_rdoc_files:
29
+ - README.rdoc
30
+ - lib/autocomplete.rb
31
+ - lib/autocomplete_controller.rb
32
+ - lib/autocomplete_helper.rb
33
+ - tasks/autocomplete_tasks.rake
34
+ files:
35
+ - MIT-LICENSE
36
+ - README.rdoc
37
+ - Rakefile
38
+ - assets/autocomplete-loading.gif
39
+ - assets/autocomplete.css
40
+ - assets/autocomplete.js
41
+ - autocomplete.gemspec
42
+ - id_rsa.pub
43
+ - init.rb
44
+ - install.rb
45
+ - lib/autocomplete.rb
46
+ - lib/autocomplete_controller.rb
47
+ - lib/autocomplete_helper.rb
48
+ - tasks/autocomplete_tasks.rake
49
+ - test/autocomplete_test.rb
50
+ - Manifest
51
+ has_rdoc: true
52
+ homepage: http://www.voja-jovanovic.info
53
+ licenses: []
54
+
55
+ post_install_message:
56
+ rdoc_options:
57
+ - --line-numbers
58
+ - --inline-source
59
+ - --title
60
+ - Autocomplete
61
+ - --main
62
+ - README.rdoc
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ hash: 3
71
+ segments:
72
+ - 0
73
+ version: "0"
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ hash: 11
80
+ segments:
81
+ - 1
82
+ - 2
83
+ version: "1.2"
84
+ requirements: []
85
+
86
+ rubyforge_project: autocomplete
87
+ rubygems_version: 1.3.7
88
+ signing_key:
89
+ specification_version: 3
90
+ summary: Insert an autocomplete-search-box inside your view
91
+ test_files:
92
+ - test/autocomplete_test.rb