repeated_auto_complete 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. data/.gitignore +21 -0
  2. data/README +102 -0
  3. data/Rakefile +52 -0
  4. data/VERSION +1 -0
  5. data/init.rb +3 -0
  6. data/lib/auto_complete.rb +49 -0
  7. data/lib/auto_complete_form_builder_helper.rb +38 -0
  8. data/lib/auto_complete_macros_helper.rb +152 -0
  9. data/lib/repeated_auto_complete.rb +4 -0
  10. data/lib/view_mapper/README +4 -0
  11. data/lib/view_mapper/has_many_auto_complete_view.rb +88 -0
  12. data/lib/view_mapper/templates/controller.rb +90 -0
  13. data/lib/view_mapper/templates/layout.html.erb +19 -0
  14. data/lib/view_mapper/templates/style.css +82 -0
  15. data/lib/view_mapper/templates/view_child_form.html.erb +16 -0
  16. data/lib/view_mapper/templates/view_form.html.erb +24 -0
  17. data/rails/init.rb +3 -0
  18. data/repeated_auto_complete.gemspec +78 -0
  19. data/test/auto_complete_form_builder_helper_test.rb +123 -0
  20. data/test/auto_complete_nested_attributes_test.rb +143 -0
  21. data/test/auto_complete_test.rb +136 -0
  22. data/test/helper.rb +14 -0
  23. data/test/view_mapper/expected_templates/_form.html.erb +26 -0
  24. data/test/view_mapper/expected_templates/_person.html.erb +22 -0
  25. data/test/view_mapper/expected_templates/create_parents.rb +16 -0
  26. data/test/view_mapper/expected_templates/edit.html.erb +11 -0
  27. data/test/view_mapper/expected_templates/index.html.erb +20 -0
  28. data/test/view_mapper/expected_templates/new.html.erb +10 -0
  29. data/test/view_mapper/expected_templates/parent.rb +15 -0
  30. data/test/view_mapper/expected_templates/show.html.erb +37 -0
  31. data/test/view_mapper/expected_templates/testies_controller.rb +92 -0
  32. data/test/view_mapper/has_many_auto_complete_view_test.rb +587 -0
  33. metadata +93 -0
@@ -0,0 +1,90 @@
1
+ class <%= controller_class_name %>Controller < ApplicationController
2
+
3
+ <% auto_complete_attributes.each do |attrib| -%>
4
+ auto_complete_for :<%= attrib[:model_name] %>, :<%= attrib[:text_field] %>
5
+ <% end -%>
6
+
7
+ # GET /<%= table_name %>
8
+ # GET /<%= table_name %>.xml
9
+ def index
10
+ @<%= table_name %> = <%= class_name %>.all
11
+
12
+ respond_to do |format|
13
+ format.html # index.html.erb
14
+ format.xml { render :xml => @<%= table_name %> }
15
+ end
16
+ end
17
+
18
+ # GET /<%= table_name %>/1
19
+ # GET /<%= table_name %>/1.xml
20
+ def show
21
+ @<%= file_name %> = <%= class_name %>.find(params[:id])
22
+
23
+ respond_to do |format|
24
+ format.html # show.html.erb
25
+ format.xml { render :xml => @<%= file_name %> }
26
+ end
27
+ end
28
+
29
+ # GET /<%= table_name %>/new
30
+ # GET /<%= table_name %>/new.xml
31
+ def new
32
+ @<%= file_name %> = <%= class_name %>.new
33
+
34
+ respond_to do |format|
35
+ format.html # new.html.erb
36
+ format.xml { render :xml => @<%= file_name %> }
37
+ end
38
+ end
39
+
40
+ # GET /<%= table_name %>/1/edit
41
+ def edit
42
+ @<%= file_name %> = <%= class_name %>.find(params[:id])
43
+ end
44
+
45
+ # POST /<%= table_name %>
46
+ # POST /<%= table_name %>.xml
47
+ def create
48
+ @<%= file_name %> = <%= class_name %>.new(params[:<%= file_name %>])
49
+
50
+ respond_to do |format|
51
+ if @<%= file_name %>.save
52
+ flash[:notice] = '<%= class_name %> was successfully created.'
53
+ format.html { redirect_to(@<%= file_name %>) }
54
+ format.xml { render :xml => @<%= file_name %>, :status => :created, :location => @<%= file_name %> }
55
+ else
56
+ format.html { render :action => "new" }
57
+ format.xml { render :xml => @<%= file_name %>.errors, :status => :unprocessable_entity }
58
+ end
59
+ end
60
+ end
61
+
62
+ # PUT /<%= table_name %>/1
63
+ # PUT /<%= table_name %>/1.xml
64
+ def update
65
+ @<%= file_name %> = <%= class_name %>.find(params[:id])
66
+
67
+ respond_to do |format|
68
+ if @<%= file_name %>.update_attributes(params[:<%= file_name %>])
69
+ flash[:notice] = '<%= class_name %> was successfully updated.'
70
+ format.html { redirect_to(@<%= file_name %>) }
71
+ format.xml { head :ok }
72
+ else
73
+ format.html { render :action => "edit" }
74
+ format.xml { render :xml => @<%= file_name %>.errors, :status => :unprocessable_entity }
75
+ end
76
+ end
77
+ end
78
+
79
+ # DELETE /<%= table_name %>/1
80
+ # DELETE /<%= table_name %>/1.xml
81
+ def destroy
82
+ @<%= file_name %> = <%= class_name %>.find(params[:id])
83
+ @<%= file_name %>.destroy
84
+
85
+ respond_to do |format|
86
+ format.html { redirect_to(<%= table_name %>_url) }
87
+ format.xml { head :ok }
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,19 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
+
4
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
5
+ <head>
6
+ <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
7
+ <title><%= controller_class_name %>: <%%= controller.action_name %></title>
8
+ <%%= stylesheet_link_tag 'scaffold' %>
9
+ <%%= javascript_include_tag :defaults %>
10
+ <%%= javascript_include_tag 'nested_attributes.js' %>
11
+ </head>
12
+ <body>
13
+
14
+ <p style="color: green"><%%= flash[:notice] %></p>
15
+
16
+ <%%= yield %>
17
+
18
+ </body>
19
+ </html>
@@ -0,0 +1,82 @@
1
+ body { background-color: #fff; color: #333; }
2
+
3
+ body, p, ol, ul, td {
4
+ font-family: verdana, arial, helvetica, sans-serif;
5
+ font-size: 13px;
6
+ line-height: 18px;
7
+ }
8
+
9
+ pre {
10
+ background-color: #eee;
11
+ padding: 10px;
12
+ font-size: 11px;
13
+ }
14
+
15
+ a { color: #000; }
16
+ a:visited { color: #666; }
17
+ a:hover { color: #fff; background-color:#000; }
18
+
19
+ .fieldWithErrors {
20
+ padding: 2px;
21
+ background-color: red;
22
+ display: table;
23
+ }
24
+
25
+ #errorExplanation {
26
+ width: 400px;
27
+ border: 2px solid red;
28
+ padding: 7px;
29
+ padding-bottom: 12px;
30
+ margin-bottom: 20px;
31
+ background-color: #f0f0f0;
32
+ }
33
+
34
+ #errorExplanation h2 {
35
+ text-align: left;
36
+ font-weight: bold;
37
+ padding: 5px 5px 5px 15px;
38
+ font-size: 12px;
39
+ margin: -7px;
40
+ background-color: #c00;
41
+ color: #fff;
42
+ }
43
+
44
+ #errorExplanation p {
45
+ color: #333;
46
+ margin-bottom: 0;
47
+ padding: 5px;
48
+ }
49
+
50
+ #errorExplanation ul li {
51
+ font-size: 12px;
52
+ list-style: square;
53
+ }
54
+
55
+ .child {
56
+ border-left: 10px solid #eee;
57
+ padding-left:10px;
58
+ }
59
+
60
+ div.auto_complete {
61
+ width: 350px;
62
+ background: #fff;
63
+ }
64
+ div.auto_complete ul {
65
+ border:1px solid #888;
66
+ margin:0;
67
+ padding:0;
68
+ width:100%;
69
+ list-style-type:none;
70
+ }
71
+ div.auto_complete ul li {
72
+ margin:0;
73
+ padding:3px;
74
+ }
75
+ div.auto_complete ul li.selected {
76
+ background-color: #ffb;
77
+ }
78
+ div.auto_complete ul strong.highlight {
79
+ color: #800;
80
+ margin:0;
81
+ padding:0;
82
+ }
@@ -0,0 +1,16 @@
1
+ <div class="child">
2
+ <% for attribute in child_model.attributes -%>
3
+ <p>
4
+ <%= child_model.name %> <%%= f.label :<%= attribute.name %> %><br />
5
+ <%- if is_auto_complete_attribute? child_model.name.downcase, attribute.name -%>
6
+ <%%= f.text_field_with_auto_complete :<%= attribute.name %>, {}, { :method => :get, :skip_style => true } %>
7
+ <%- else -%>
8
+ <%%= f.<%= attribute.field_type %> :<%= attribute.name %> %>
9
+ <%- end -%>
10
+ </p>
11
+ <% end -%>
12
+ <p>
13
+ <%%= f.hidden_field :_delete, :class => 'delete' %>
14
+ <%%= remove_child_link 'remove', f %>
15
+ </p>
16
+ </div>
@@ -0,0 +1,24 @@
1
+ <%%= f.error_messages %>
2
+ <% for attribute in attributes -%>
3
+
4
+ <p>
5
+ <%%= f.label :<%= attribute.name %> %><br />
6
+ <%- if is_auto_complete_attribute? singular_name, attribute.name -%>
7
+ <%%= f.text_field_with_auto_complete :<%= attribute.name %>, {}, { :method => :get, :skip_style => true } %>
8
+ <%- else -%>
9
+ <%%= f.<%= attribute.field_type %> :<%= attribute.name %> %>
10
+ <%- end -%>
11
+ </p>
12
+ <% end -%>
13
+ <% child_models.each do |child_model| -%>
14
+
15
+ <div id='<%= child_model.name.underscore %>_children'>
16
+ <%% f.fields_for :<%= child_model.name.underscore.pluralize %> do |<%= child_model.name.underscore %>_form| %>
17
+ <%%= render :partial => '<%= child_model.name.underscore %>', :locals => { :f => <%= child_model.name.underscore %>_form } %>
18
+ <%% end %>
19
+ </div>
20
+
21
+ <p>
22
+ <%%= add_child_link 'Add a <%= child_model.name %>', '<%= child_model.name.underscore %>', f %>
23
+ </p>
24
+ <% end -%>
data/rails/init.rb ADDED
@@ -0,0 +1,3 @@
1
+ ActionController::Base.send :include, AutoComplete
2
+ ActionController::Base.helper AutoCompleteMacrosHelper
3
+ ActionView::Helpers::FormBuilder.send :include, AutoCompleteFormBuilderHelper
@@ -0,0 +1,78 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{repeated_auto_complete}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Pat Shaughnessy"]
12
+ s.date = %q{2009-11-25}
13
+ s.description = %q{auto_complete plugin refactored to handle complex forms and named scopes}
14
+ s.email = %q{pat@patshaughnessy.net}
15
+ s.extra_rdoc_files = [
16
+ "README"
17
+ ]
18
+ s.files = [
19
+ ".gitignore",
20
+ "README",
21
+ "Rakefile",
22
+ "VERSION",
23
+ "init.rb",
24
+ "lib/auto_complete.rb",
25
+ "lib/auto_complete_form_builder_helper.rb",
26
+ "lib/auto_complete_macros_helper.rb",
27
+ "lib/repeated_auto_complete.rb",
28
+ "lib/view_mapper/README",
29
+ "lib/view_mapper/has_many_auto_complete_view.rb",
30
+ "lib/view_mapper/templates/controller.rb",
31
+ "lib/view_mapper/templates/layout.html.erb",
32
+ "lib/view_mapper/templates/style.css",
33
+ "lib/view_mapper/templates/view_child_form.html.erb",
34
+ "lib/view_mapper/templates/view_form.html.erb",
35
+ "rails/init.rb",
36
+ "repeated_auto_complete.gemspec",
37
+ "test/auto_complete_form_builder_helper_test.rb",
38
+ "test/auto_complete_nested_attributes_test.rb",
39
+ "test/auto_complete_test.rb",
40
+ "test/helper.rb",
41
+ "test/view_mapper/expected_templates/_form.html.erb",
42
+ "test/view_mapper/expected_templates/_person.html.erb",
43
+ "test/view_mapper/expected_templates/create_parents.rb",
44
+ "test/view_mapper/expected_templates/edit.html.erb",
45
+ "test/view_mapper/expected_templates/index.html.erb",
46
+ "test/view_mapper/expected_templates/new.html.erb",
47
+ "test/view_mapper/expected_templates/parent.rb",
48
+ "test/view_mapper/expected_templates/show.html.erb",
49
+ "test/view_mapper/expected_templates/testies_controller.rb",
50
+ "test/view_mapper/has_many_auto_complete_view_test.rb"
51
+ ]
52
+ s.homepage = %q{http://patshaughnessy.net/repeated_auto_complete}
53
+ s.rdoc_options = ["--charset=UTF-8"]
54
+ s.require_paths = ["lib"]
55
+ s.rubygems_version = %q{1.3.5}
56
+ s.summary = %q{auto_complete plugin refactored to handle complex forms and named scopes}
57
+ s.test_files = [
58
+ "test/auto_complete_form_builder_helper_test.rb",
59
+ "test/auto_complete_nested_attributes_test.rb",
60
+ "test/auto_complete_test.rb",
61
+ "test/helper.rb",
62
+ "test/view_mapper/expected_templates/create_parents.rb",
63
+ "test/view_mapper/expected_templates/parent.rb",
64
+ "test/view_mapper/expected_templates/testies_controller.rb",
65
+ "test/view_mapper/has_many_auto_complete_view_test.rb"
66
+ ]
67
+
68
+ if s.respond_to? :specification_version then
69
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
70
+ s.specification_version = 3
71
+
72
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
73
+ else
74
+ end
75
+ else
76
+ end
77
+ end
78
+
@@ -0,0 +1,123 @@
1
+ require 'helper'
2
+
3
+ class Person
4
+ attr_accessor :name, :id
5
+ def initialize name, id = nil
6
+ @name, @id = name, id
7
+ end
8
+ def to_param
9
+ id.to_s
10
+ end
11
+ end
12
+
13
+ class AutoCompleteFormBuilderHelperTest < Test::Unit::TestCase
14
+
15
+ include AutoCompleteMacrosHelper
16
+ include ActionView::Helpers::UrlHelper
17
+ include ActionView::Helpers::TagHelper
18
+ include ActionView::Helpers::FormHelper
19
+
20
+ def setup
21
+
22
+ @existing_person = Person.new "Existing Person", 1234
23
+ @person = Person.new "New Person"
24
+
25
+ controller_class = Class.new do
26
+ def url_for(options)
27
+ url = "http://www.example.com/"
28
+ url << options[:action].to_s if options and options[:action]
29
+ url
30
+ end
31
+ end
32
+ @controller = controller_class.new
33
+
34
+ end
35
+
36
+ def test_two_auto_complete_fields_have_different_ids
37
+ id_attribute_pattern = /id=\"[^\"]*\"/i
38
+ _erbout = ''
39
+ _erbout2 = ''
40
+ fields_for('group[person_attributes][]', @person) do |f|
41
+ _erbout.concat f.text_field_with_auto_complete(:name)
42
+ _erbout2.concat f.text_field_with_auto_complete(:name)
43
+ end
44
+ assert_equal [], _erbout.scan(id_attribute_pattern) & _erbout2.scan(id_attribute_pattern)
45
+ end
46
+
47
+ def test_compare_macro_to_fields_for
48
+ standard_auto_complete_html = text_field_with_auto_complete(:person, :name)
49
+
50
+ _erbout = ''
51
+ fields_for('group[person_attributes][]', @person) do |f|
52
+ _erbout.concat f.text_field_with_auto_complete(:name)
53
+ end
54
+
55
+ assert_equal standard_auto_complete_html,
56
+ _erbout.gsub(/group\[person_attributes\]\[\]/, 'person').gsub(/person_[0-9]+_name/, 'person_name').gsub(/paramName:'person\[name\]'/, '')
57
+ end
58
+
59
+ def test_ajax_url
60
+ _erbout = ''
61
+ fields_for('group[person_attributes][]', @person) do |f|
62
+ _erbout.concat f.text_field_with_auto_complete(:name)
63
+ end
64
+ assert _erbout.index('http://www.example.com/auto_complete_for_person_name')
65
+ end
66
+
67
+ def test_ajax_param
68
+ _erbout = ''
69
+ fields_for('group[person_attributes][]', @person) do |f|
70
+ _erbout.concat f.text_field_with_auto_complete(:name)
71
+ end
72
+ assert _erbout.index("{paramName:'person[name]'}")
73
+ end
74
+
75
+ def test_object_value
76
+ _erbout = ''
77
+ fields_for('group[person_attributes][]', @existing_person) do |f|
78
+ _erbout.concat f.text_field_with_auto_complete(:name)
79
+ end
80
+ assert _erbout.index('value="Existing Person"')
81
+ end
82
+
83
+ def test_auto_index_value_for_existing_record
84
+ _erbout = ''
85
+ fields_for('group[person_attributes][]', @existing_person) do |f|
86
+ _erbout.concat f.text_field_with_auto_complete(:name)
87
+ end
88
+ assert _erbout.index("[1234]")
89
+ end
90
+
91
+ def test_auto_index_value_for_new_record
92
+ _erbout = ''
93
+ fields_for('group[person_attributes][]', @person) do |f|
94
+ _erbout.concat f.text_field_with_auto_complete(:name)
95
+ end
96
+ assert _erbout.index("[]")
97
+ end
98
+
99
+ def test_child_index_fields_for_option
100
+ _erbout = ''
101
+ fields_for 'group[person_attributes][]', @person, { :child_index => 5678 } do |f|
102
+ _erbout.concat f.text_field_with_auto_complete(:name, {}, { :method => :get })
103
+ assert _erbout.index('person_5678_name')
104
+ end
105
+ end
106
+
107
+ def test_child_index_completion_option
108
+ _erbout = ''
109
+ fields_for('group[person_attributes][]', @person) do |f|
110
+ _erbout.concat f.text_field_with_auto_complete(:name, {}, { :method => :get, :child_index => 1234 })
111
+ assert _erbout.index('person_1234_name')
112
+ end
113
+ end
114
+
115
+ def test_child_index_completion_option_overrides_fields_for_option
116
+ _erbout = ''
117
+ fields_for('group[person_attributes][]', @person, { :child_index => 5678 }) do |f|
118
+ _erbout.concat f.text_field_with_auto_complete(:name, {}, { :method => :get, :child_index => 1234 })
119
+ assert _erbout.index('person_1234_name')
120
+ end
121
+ end
122
+
123
+ end