maiha-sexy_auto_complete 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README +83 -0
- data/Rakefile +22 -0
- data/files/multicontrols.js +37 -0
- data/init.rb +16 -0
- data/install.rb +1 -0
- data/lib/auto_complete/controller.rb +76 -0
- data/lib/auto_complete/helper.rb +48 -0
- data/lib/auto_complete.rb +8 -0
- data/tasks/auto_complete_tasks.rake +4 -0
- data/test/auto_complete_test.rb +8 -0
- data/uninstall.rb +1 -0
- metadata +64 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 [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.
|
data/README
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
AutoComplete
|
2
|
+
============
|
3
|
+
|
4
|
+
Rails plugin for better auto_complete, especially it gets along with ActiveScaffold nested forms
|
5
|
+
|
6
|
+
Methods
|
7
|
+
=======
|
8
|
+
|
9
|
+
[helper]
|
10
|
+
* auto_complete_for(record_name, column_name, field_name, target_options = {}, suggest_options = {}, trigger_options = {})
|
11
|
+
create text_field and candidate_area and callback elements like text_field_with_auto_complete
|
12
|
+
|
13
|
+
* auto_complete_javascript
|
14
|
+
return javascript string tag for this plugin
|
15
|
+
|
16
|
+
* auto_complete_stylesheet
|
17
|
+
return stylesheet string for this plugin
|
18
|
+
|
19
|
+
* auto_complete_includes
|
20
|
+
return javscript and styleshet string for this plugin
|
21
|
+
|
22
|
+
[controller]
|
23
|
+
* auto_complete(records, options = {}, &block)
|
24
|
+
create ul and li elements for the AJAX autocomplete requests
|
25
|
+
records : candidate objects
|
26
|
+
options :
|
27
|
+
- :blank : a message string when there are no candidates
|
28
|
+
(set false if you don't want the message)
|
29
|
+
block : a block to create candidate message from a record.
|
30
|
+
:to_label, :name, :id methods are used in order for default
|
31
|
+
|
32
|
+
Example
|
33
|
+
=======
|
34
|
+
|
35
|
+
[view]
|
36
|
+
<%- @user = User.new ->
|
37
|
+
<%= auto_complete_includes %>
|
38
|
+
<%= auto_complete_for :user, :pref_id %>
|
39
|
+
|
40
|
+
[controller]
|
41
|
+
class UserController < ApplicationController
|
42
|
+
include AutoComplete
|
43
|
+
|
44
|
+
def auto_complete_pref_id
|
45
|
+
# form value is set to @input automatically
|
46
|
+
records = Pref.find(:all, :conditions=>["name LIKE ?", "%#{@input}%"], :limit=>10)
|
47
|
+
auto_complete(records, &:name)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
With ActiveScaffold
|
52
|
+
===================
|
53
|
+
[helper]
|
54
|
+
def pref_id_form_column(record, field_name)
|
55
|
+
opts = {:controller=>:auto_complete, :action=>:pref_id, :name=>field_name}
|
56
|
+
auto_complete_for :record, :pref_id, opts, {:style=>"width:600px;"}
|
57
|
+
end
|
58
|
+
|
59
|
+
[controller]
|
60
|
+
class AutoCompleteController < ApplicationController
|
61
|
+
include AutoComplete
|
62
|
+
|
63
|
+
def pref_id
|
64
|
+
conds = ["id::varchar ~* ?", Regexp.escape(@input)]
|
65
|
+
records = Pref.find(:all, :conditions=>conds, :order=>:id, :limit=>10)
|
66
|
+
auto_complete(records) do |pref|
|
67
|
+
value = auto_complete_connect(params[:id], pref.id)
|
68
|
+
label = pref.name
|
69
|
+
"%s %s" % [value, label]
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
Advanced Settings
|
75
|
+
=================
|
76
|
+
|
77
|
+
[controller]
|
78
|
+
* auto_complete_response_not_implemented
|
79
|
+
This string returns via Ajax autocompletion request when ActionController::UnknownAction is raised.
|
80
|
+
If you want normal exception, override this method to return nil.
|
81
|
+
|
82
|
+
|
83
|
+
Copyright (c) 2008 maiha@wota.jp, released under the MIT license
|
data/Rakefile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
|
5
|
+
desc 'Default: run unit tests.'
|
6
|
+
task :default => :test
|
7
|
+
|
8
|
+
desc 'Test the auto_complete plugin.'
|
9
|
+
Rake::TestTask.new(:test) do |t|
|
10
|
+
t.libs << 'lib'
|
11
|
+
t.pattern = 'test/**/*_test.rb'
|
12
|
+
t.verbose = true
|
13
|
+
end
|
14
|
+
|
15
|
+
desc 'Generate documentation for the auto_complete plugin.'
|
16
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
17
|
+
rdoc.rdoc_dir = 'rdoc'
|
18
|
+
rdoc.title = 'AutoComplete'
|
19
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
20
|
+
rdoc.rdoc_files.include('README')
|
21
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
22
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
function getElementsByAttributeName(node, attrname)
|
2
|
+
{
|
3
|
+
var a = [];
|
4
|
+
var re = new RegExp('\\b' + attrname + '\\b');
|
5
|
+
var els = node.getElementsByTagName("*");
|
6
|
+
for(var i=0,j=els.length; i<j; i++)
|
7
|
+
if(els[i].getAttribute(attrname)) a.push(els[i]);
|
8
|
+
return a;
|
9
|
+
}
|
10
|
+
|
11
|
+
Object.extend(Ajax.Autocompleter.prototype,{
|
12
|
+
selectEntry: function() {
|
13
|
+
this.active = false;
|
14
|
+
var defs = getElementsByAttributeName(this.getCurrentEntry(), 'connect');
|
15
|
+
|
16
|
+
if (defs.length == 0) {
|
17
|
+
this.updateElement(this.getCurrentEntry());
|
18
|
+
} else {
|
19
|
+
for (var i = 0; i < defs.length; i++) {
|
20
|
+
var connectid = defs[i].getAttribute("connect");
|
21
|
+
if ($(connectid)) {
|
22
|
+
if ($(connectid).tagName == "INPUT"){
|
23
|
+
$(connectid).value = defs[i].childNodes[0].nodeValue;
|
24
|
+
} else {
|
25
|
+
$(connectid).innerHTML = defs[i].childNodes[0].nodeValue;
|
26
|
+
}
|
27
|
+
}
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
31
|
+
if (this.options.afterUpdateElement)
|
32
|
+
this.options.afterUpdateElement(this.element, this.getCurrentEntry());
|
33
|
+
|
34
|
+
this.element.focus();
|
35
|
+
}
|
36
|
+
});
|
37
|
+
|
data/init.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# install javascripts
|
2
|
+
|
3
|
+
src = File.dirname(__FILE__) + "/files/multicontrols.js"
|
4
|
+
dst = RAILS_ROOT + "/public/javascripts/multicontrols.js"
|
5
|
+
if !File.exist?(dst) or File.mtime(dst) < File.mtime(src)
|
6
|
+
if (logger = ActionController::Base.logger)
|
7
|
+
logger.debug "[AutoComplete plugin] install multicontrols.js to #{dst}"
|
8
|
+
end
|
9
|
+
FileUtils.cp(src, dst)
|
10
|
+
end
|
11
|
+
|
12
|
+
# apply new methods to ApplicationHelper
|
13
|
+
|
14
|
+
ApplicationHelper.module_eval do
|
15
|
+
include AutoComplete::Helper
|
16
|
+
end
|
data/install.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# Install hook code here
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module AutoComplete
|
2
|
+
module Controller
|
3
|
+
private
|
4
|
+
def auto_complete_read_input
|
5
|
+
# [params]
|
6
|
+
# "record" => {"item_locations"=>{"1229373405139"=>{"position"=>"ITN"}}},
|
7
|
+
# "path" => "record[item_locations][1229373405139][position]",
|
8
|
+
@input = params[:path].to_s.split(%r{[\[|\]/]+}).inject(params){|hash, key| hash[key]}.to_s.strip
|
9
|
+
if @input.blank?
|
10
|
+
render :nothing=>true
|
11
|
+
return false
|
12
|
+
end
|
13
|
+
return true
|
14
|
+
end
|
15
|
+
|
16
|
+
def auto_complete(records, options = {}, &block)
|
17
|
+
block ||= proc{|r| r.respond_to?(:to_label) ? r.to_label : (r.respond_to?(:name) ? r.name : r.id)}
|
18
|
+
if records.blank? and !(options[:blank] == false)
|
19
|
+
suggest = options[:blank]
|
20
|
+
suggest = auto_complete_response_not_found unless suggest.is_a?(String)
|
21
|
+
else
|
22
|
+
suggest = records.map{|r| block.call(r)}
|
23
|
+
end
|
24
|
+
auto_complete_render(suggest)
|
25
|
+
end
|
26
|
+
|
27
|
+
def auto_complete_wrap(response)
|
28
|
+
case response
|
29
|
+
when Array
|
30
|
+
"<ul>%s</ul>" % response.map{|i| "<li>#{i}</li>"}.join
|
31
|
+
when /^<ul.*?>/
|
32
|
+
response
|
33
|
+
when /^<li.*?>/
|
34
|
+
"<ul>#{response}</ul>"
|
35
|
+
else
|
36
|
+
"<ul><li>#{response}#{auto_complete_nop}</li></ul>"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def auto_complete_response_not_found
|
41
|
+
"No Match"
|
42
|
+
end
|
43
|
+
|
44
|
+
def auto_complete_response_not_implemented
|
45
|
+
"Cannot complete : Please define [#{controller_name.to_s.classify}##{action_name}] action"
|
46
|
+
end
|
47
|
+
|
48
|
+
def auto_complete_connect(to, data = nil)
|
49
|
+
"<span connect='#{to}'>#{data}</span>"
|
50
|
+
end
|
51
|
+
|
52
|
+
def auto_complete_nop
|
53
|
+
"<span connect='__no_such_element__' style='display:none;'></span>"
|
54
|
+
end
|
55
|
+
|
56
|
+
def auto_complete_render(value)
|
57
|
+
value = auto_complete_wrap(value)
|
58
|
+
# logger.debug "[AUTO COMPLETE] (%s) -> %s" % [@input, value]
|
59
|
+
render :text=>value
|
60
|
+
end
|
61
|
+
|
62
|
+
def rescue_action(error)
|
63
|
+
# I don't know why it fails to accessing to ActionController::UnknownAction directly
|
64
|
+
# => uninitialized constant ActionWebService::Dispatcher::ActionController::UnknownAction
|
65
|
+
case error.class.name
|
66
|
+
when "ActionController::UnknownAction"
|
67
|
+
if auto_complete_response_not_implemented
|
68
|
+
auto_complete_render auto_complete_response_not_implemented
|
69
|
+
return
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
super
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module AutoComplete
|
2
|
+
module Helper
|
3
|
+
def auto_complete_for(record_name, column_name, target_options = {}, suggest_options = {}, trigger_options = {})
|
4
|
+
record = instance_variable_get("@#{record_name}")
|
5
|
+
model_name = record.class.name.demodulize.underscore
|
6
|
+
controller = target_options.delete(:controller) || model_name
|
7
|
+
action = target_options.delete(:action) || "auto_complete_#{column_name}"
|
8
|
+
field_name = target_options.delete(:name) || column_name
|
9
|
+
|
10
|
+
# target
|
11
|
+
target_id = field_name.gsub(/\[|\]/, '_')
|
12
|
+
options = {:name=>field_name, :id=>target_id, :class=>"#{column_name}-input", :size=>20}.merge(trigger_options)
|
13
|
+
target = input(record_name, column_name, options)
|
14
|
+
|
15
|
+
# suggest
|
16
|
+
options = {:id=>"#{target_id}_auto_complete", :class=>"auto_complete", :style=>"width:400px;"}.merge(suggest_options)
|
17
|
+
suggest = content_tag('div', '', options)
|
18
|
+
|
19
|
+
# trigger
|
20
|
+
url = {:controller=>controller, :action=>action, :id=>target_id, :path=>field_name}
|
21
|
+
options = {:url=>url, :min_chars=>3}.update(trigger_options)
|
22
|
+
trigger = auto_complete_field target_id, options
|
23
|
+
|
24
|
+
target + suggest + trigger
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
def auto_complete_includes
|
29
|
+
auto_complete_javascript + auto_complete_stylesheet
|
30
|
+
end
|
31
|
+
|
32
|
+
def auto_complete_javascript
|
33
|
+
javascript_include_tag "multicontrols"
|
34
|
+
end
|
35
|
+
|
36
|
+
def auto_complete_stylesheet
|
37
|
+
super +
|
38
|
+
content_tag('style', <<-EOT, :type => 'text/css')
|
39
|
+
div.auto_complete {
|
40
|
+
color: black;
|
41
|
+
}
|
42
|
+
div.auto_complete ul li {
|
43
|
+
background-color: #fff;
|
44
|
+
}
|
45
|
+
EOT
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/uninstall.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# Uninstall hook code here
|
metadata
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: maiha-sexy_auto_complete
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: "0.1"
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- maiha
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-12-16 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: ""
|
17
|
+
email: maiha@wota.jp
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files: []
|
23
|
+
|
24
|
+
files:
|
25
|
+
- MIT-LICENSE
|
26
|
+
- README
|
27
|
+
- Rakefile
|
28
|
+
- files/multicontrols.js
|
29
|
+
- init.rb
|
30
|
+
- install.rb
|
31
|
+
- lib/auto_complete.rb
|
32
|
+
- lib/auto_complete/controller.rb
|
33
|
+
- lib/auto_complete/helper.rb
|
34
|
+
- tasks/auto_complete_tasks.rake
|
35
|
+
- test/auto_complete_test.rb
|
36
|
+
- uninstall.rb
|
37
|
+
has_rdoc: true
|
38
|
+
homepage: http://github.com/maiha/sexy_auto_complete
|
39
|
+
post_install_message:
|
40
|
+
rdoc_options: []
|
41
|
+
|
42
|
+
require_paths:
|
43
|
+
- lib
|
44
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: "0"
|
49
|
+
version:
|
50
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: "0"
|
55
|
+
version:
|
56
|
+
requirements: []
|
57
|
+
|
58
|
+
rubyforge_project:
|
59
|
+
rubygems_version: 1.2.0
|
60
|
+
signing_key:
|
61
|
+
specification_version: 2
|
62
|
+
summary: ""
|
63
|
+
test_files: []
|
64
|
+
|