king_views 1.1.6 → 1.2.0

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.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +23 -0
  3. data/Gemfile +19 -0
  4. data/Rakefile +5 -28
  5. data/king_form/lib/king_form/builder/base.rb +23 -9
  6. data/king_form/lib/king_form/builder/definition_list.rb +8 -4
  7. data/king_form/lib/king_form/builder/form_fields.rb +3 -2
  8. data/king_form/lib/king_form/builder/form_fields_overrides.rb +5 -5
  9. data/king_form/lib/king_form/builder/labeled.rb +3 -3
  10. data/king_form/lib/king_form/helper.rb +21 -4
  11. data/king_form/lib/king_form/nested_form_helper.rb +9 -9
  12. data/king_form/lib/king_form/overrides.rb +13 -13
  13. data/king_format/lib/helpers/formatting_helper.rb +21 -16
  14. data/king_format/lib/helpers/money_helper.rb +6 -6
  15. data/king_format/lib/king_format.rb +2 -0
  16. data/king_format/lib/model_mixins/has_date_fields.rb +6 -2
  17. data/king_format/lib/model_mixins/has_money_fields.rb +6 -2
  18. data/king_format/lib/model_mixins/has_percent_fields.rb +5 -1
  19. data/king_list/Rakefile +2 -13
  20. data/king_list/lib/king_list/builder/show.rb +9 -6
  21. data/king_list/lib/king_list/builder/table.rb +29 -72
  22. data/king_list/lib/king_list/list_helper.rb +60 -63
  23. data/king_views.gemspec +24 -71
  24. data/spec/king_list_spec.rb +19 -0
  25. data/spec/rails_app/Rakefile +7 -0
  26. data/spec/rails_app/app/controllers/application_controller.rb +4 -0
  27. data/spec/rails_app/app/controllers/posts_controller.rb +6 -0
  28. data/spec/rails_app/app/helpers/application_helper.rb +2 -0
  29. data/spec/rails_app/app/models/comment.rb +3 -0
  30. data/spec/rails_app/app/models/person.rb +3 -0
  31. data/spec/rails_app/app/models/post.rb +4 -0
  32. data/spec/rails_app/app/views/layouts/application.html.erb +14 -0
  33. data/spec/rails_app/app/views/posts/index.haml +23 -0
  34. data/spec/rails_app/config.ru +4 -0
  35. data/spec/rails_app/config/application.rb +44 -0
  36. data/spec/rails_app/config/boot.rb +10 -0
  37. data/spec/rails_app/config/database.yml +22 -0
  38. data/spec/rails_app/config/environment.rb +5 -0
  39. data/spec/rails_app/config/environments/development.rb +26 -0
  40. data/spec/rails_app/config/environments/production.rb +49 -0
  41. data/spec/rails_app/config/environments/test.rb +35 -0
  42. data/spec/rails_app/config/initializers/backtrace_silencers.rb +7 -0
  43. data/spec/rails_app/config/initializers/inflections.rb +10 -0
  44. data/spec/rails_app/config/initializers/mime_types.rb +5 -0
  45. data/spec/rails_app/config/initializers/secret_token.rb +7 -0
  46. data/spec/rails_app/config/initializers/session_store.rb +8 -0
  47. data/spec/rails_app/config/locales/en.yml +5 -0
  48. data/spec/rails_app/config/routes.rb +60 -0
  49. data/spec/rails_app/db/migrate/20110306212208_create_posts.rb +14 -0
  50. data/spec/rails_app/db/migrate/20110306212250_create_comments.rb +15 -0
  51. data/spec/rails_app/db/migrate/20110420222224_create_people.rb +15 -0
  52. data/spec/rails_app/db/schema.rb +30 -0
  53. data/spec/rails_app/public/404.html +26 -0
  54. data/spec/rails_app/public/422.html +26 -0
  55. data/spec/rails_app/public/500.html +26 -0
  56. data/spec/rails_app/public/favicon.ico +0 -0
  57. data/spec/rails_app/script/rails +6 -0
  58. data/spec/spec_helper.rb +65 -0
  59. metadata +238 -47
  60. data/king_list/test/king_list_test.rb +0 -9
  61. data/king_list/test/test_helper.rb +0 -3
@@ -7,7 +7,7 @@ module KingFormat
7
7
  # -
8
8
  module MoneyHelper
9
9
 
10
- # returns the keys from money symbols als Hash{array} for select options
10
+ # returns the keys from money symbols als Hash{array} for select options
11
11
  def money_selects
12
12
  money_symbols.keys.sort
13
13
  end
@@ -18,8 +18,8 @@ module KingFormat
18
18
  # 'USD' => {:unit=>'$'}
19
19
  def money_symbols
20
20
  @money_symbols ||= begin
21
- eur = {:format => '%n %u', :precision=> '2',:delimiter=>'.', :separator=>','}
22
- dol = {:format => '%n %u', :precision=> '2',:delimiter=>',', :separator=>'.'}
21
+ eur = {:format => '%n %u', :precision => '2',:delimiter => '.', :separator => ','}
22
+ dol = {:format => '%u%n', :precision => '2',:delimiter => ',', :separator => '.'}
23
23
  {
24
24
  'EUR' => eur.merge(:unit=>'€'),
25
25
  'GBP' => dol.merge(:unit=>'£'),
@@ -37,7 +37,7 @@ module KingFormat
37
37
  'HUF' => nil,
38
38
  'LTL' => nil,
39
39
  'LVL' => nil,
40
- 'PLN' => nil,
40
+ 'PLN' => eur.merge(:unit=>'zł', :delimiter => ' '),
41
41
  'RON' => nil,
42
42
  'SEK' => nil,
43
43
  'SKK' => nil,
@@ -60,6 +60,6 @@ module KingFormat
60
60
  }
61
61
  end
62
62
  end
63
-
63
+
64
64
  end
65
- end
65
+ end
@@ -1,4 +1,6 @@
1
+ require 'active_support'
1
2
  require 'active_support/deprecation'
3
+ require 'active_support/version'
2
4
  # KingFormat
3
5
  $LOAD_PATH << File.expand_path(File.dirname(__FILE__))
4
6
 
@@ -2,7 +2,11 @@ module KingFormat
2
2
  module DateFields
3
3
 
4
4
  def self.included(base)
5
- base.send :class_inheritable_accessor, :date_fields
5
+ if ActiveSupport::VERSION::MAJOR == 3 && ActiveSupport::VERSION::MINOR > 0
6
+ base.class_attribute :date_fields
7
+ else
8
+ base.send :class_inheritable_accessor, :date_fields
9
+ end
6
10
  base.date_fields = []
7
11
  base.extend(ClassMethods)
8
12
  end
@@ -37,6 +41,6 @@ module KingFormat
37
41
  self.class.date_fields.include?(fieldname.to_sym)
38
42
  end
39
43
  end
40
-
44
+
41
45
  end #Fields
42
46
  end#KingFormat
@@ -2,7 +2,11 @@ module KingFormat
2
2
  module MoneyFields
3
3
 
4
4
  def self.included(base)
5
- base.send :class_inheritable_accessor, :money_fields
5
+ if ActiveSupport::VERSION::MAJOR == 3 && ActiveSupport::VERSION::MINOR > 0
6
+ base.class_attribute :money_fields
7
+ else
8
+ base.send :class_inheritable_accessor, :money_fields
9
+ end
6
10
  base.money_fields = []
7
11
  base.extend(ClassMethods)
8
12
  end
@@ -37,6 +41,6 @@ module KingFormat
37
41
  self.class.is_money_field?(fieldname)
38
42
  end
39
43
  end
40
-
44
+
41
45
  end #Fields
42
46
  end#KingFormat
@@ -5,7 +5,11 @@ module KingFormat
5
5
  module PercentFields
6
6
 
7
7
  def self.included(base)
8
- base.send :class_inheritable_accessor, :percent_fields
8
+ if ActiveSupport::VERSION::MAJOR == 3 && ActiveSupport::VERSION::MINOR > 0
9
+ base.class_attribute :percent_fields
10
+ else
11
+ base.send :class_inheritable_accessor, :percent_fields
12
+ end
9
13
  base.percent_fields = []
10
14
  base.extend(ClassMethods)
11
15
  end
@@ -1,19 +1,8 @@
1
1
  require 'rake'
2
- require 'rake/testtask'
3
- require 'rake/rdoctask'
2
+ require 'rdoc/task'
4
3
 
5
- desc 'Default: run unit tests.'
6
- task :default => :test
7
4
 
8
- desc 'Test the king_list plugin.'
9
- Rake::TestTask.new(:test) do |t|
10
- t.libs << 'lib'
11
- t.libs << 'test'
12
- t.pattern = 'test/**/*_test.rb'
13
- t.verbose = true
14
- end
15
-
16
- desc 'Generate documentation for the king_list plugin.'
5
+ desc 'Generate documentation for the king_list.'
17
6
  Rake::RDocTask.new(:rdoc) do |rdoc|
18
7
  rdoc.rdoc_dir = 'rdoc'
19
8
  rdoc.title = 'KingList'
@@ -45,6 +45,9 @@ module KingList
45
45
  object = @object
46
46
  end
47
47
 
48
+ dt_options = options.delete(:dt_options) if options.has_key?(:dt_options)
49
+ dd_options = options.delete(:dd_options) if options.has_key?(:dd_options)
50
+
48
51
  # Use given caption or translate column title
49
52
  caption = options.delete(:caption) || object.class.human_attribute_name(field_name.to_s)
50
53
 
@@ -57,15 +60,15 @@ module KingList
57
60
  end
58
61
 
59
62
  # Against HTML validity warnings
60
- caption = '&nbsp;' if caption.blank?
61
- value = '&nbsp;' if value.blank?
63
+ caption = '&nbsp;'.html_safe if caption.blank?
64
+ value = '&nbsp;'.html_safe if value.blank?
62
65
 
63
66
  @template.capture_haml do
64
- @template.haml_tag :dt, caption, options
65
- @template.haml_tag :dd, value, options
67
+ @template.haml_tag :dt, caption, dt_options || options
68
+ @template.haml_tag :dd, value, dd_options || options
66
69
  end
67
70
  end
68
-
71
+
69
72
  end #class
70
73
  end # module
71
- end # module
74
+ end # module
@@ -2,18 +2,13 @@ module KingList
2
2
  module Builder
3
3
  class Table
4
4
 
5
- attr_accessor :mode, :current_record, :current_column_number, :number_of_columns, :sorting
5
+ attr_accessor :mode, :current_record, :sorting
6
6
 
7
7
  def initialize(template, collection, &block)
8
8
  @template = template
9
9
  @collection = collection
10
10
  end
11
11
 
12
- def start_row(data)
13
- self.current_column_number = 0
14
- self.current_record = data
15
- end
16
-
17
12
  # Build a column for a table
18
13
  #
19
14
  # ==== Parameter
@@ -33,37 +28,29 @@ module KingList
33
28
  # :td_options{Symbol=>String}:: options for the <td>
34
29
  # :class:: the class to set on the th
35
30
  # :class => class as Symbol or String used on TH and TD used f.ex. for alignment.
36
- def column(field_name, options = {})
37
- options = options.deep_clone # for not changing outer variable
38
- th_options = options[:th_options] || {}
39
- td_options = options[:td_options] || {}
31
+ def column(field_name, opts = {})
32
+ opts = opts.deep_clone # for not changing outer variable
33
+ th_options = opts[:th_options] || {}
34
+ td_options = opts[:td_options] || {}
40
35
 
41
36
  # Use given object from options (or current_record as default)
42
- object = options.has_key?(:object) ? options.delete(:object) : current_record
37
+ object = opts.has_key?(:object) ? opts.delete(:object) : current_record
43
38
 
44
39
  # :class given so add to TH and TD f.ex cell alignment :class=>'rgt'
45
- if css_class = options.delete(:class)
40
+ if css_class = opts.delete(:class)
46
41
  (th_options[:class] ||= '') << " #{css_class}"
47
42
  (td_options[:class] ||= '') << " #{css_class}"
48
43
  end
49
44
 
50
- self.current_column_number += 1
51
-
52
45
  case mode
53
- when :counter
54
- self.number_of_columns ||= 0
55
- self.number_of_columns += 1
56
- nil
57
-
58
46
  when :header
59
47
  # Take option or translate column title
60
- title_text = options[:title] || object.class.human_attribute_name(field_name.to_s)
61
-
48
+ title_text = opts[:title] || object.class.human_attribute_name(field_name.to_s)
62
49
  # whole table has sorting enabled and current column has NOT :sorting=>false
63
50
  # => put sorting link into header
64
- if sorting && (options.delete(:sorting) != false)
51
+ if sorting && (opts.delete(:sorting) != false)
65
52
  # Use given sort_fields or try to detect them automatic
66
- sort_fields = options.delete(:sort_fields) || object.class.table_name + '.' + field_name.to_s
53
+ sort_fields = opts.delete(:sort_fields) || object.class.table_name + '.' + field_name.to_s
67
54
  # Convert to comma separated string if it is an array
68
55
  sort_fields = sort_fields.join(',') if sort_fields.is_a?(Array)
69
56
  # Swap ASC/DESC on every click of the same column title
@@ -78,43 +65,22 @@ module KingList
78
65
  # otherwise just plain text (no sorting link)
79
66
  title = title_text
80
67
  end
81
- # mark the first and last columns with css classes
82
- if self.current_column_number == 1
83
- (th_options[:class] ||= '') << ' first'
84
- elsif self.current_column_number == self.number_of_columns
85
- (th_options[:class] ||= '') << ' last'
86
- end
87
- @template.capture_haml do
88
- @template.haml_tag(:th, title.to_s, th_options)
89
- end
68
+ "<th #{ to_attr(th_options) }>#{title.to_s}</th>".html_safe
90
69
 
91
70
  when :content
92
71
  # Use given value (or formatted value as default)
93
- value = options.delete(:value) || @template.strfval(object, field_name, value)
94
-
72
+ value = opts.delete(:value) || @template.strfval(object, field_name, value)
95
73
  # If link option is set, then link to this
96
- # === Example #
74
+ # === Example
97
75
  # :link => true : uses current object show link
98
76
  # :link => nil or blank no linking
99
- if link = options.delete(:link)
100
- # link to current_oject if true given
77
+ if link = opts.delete(:link)
78
+ # link to current_object if true given
101
79
  link = object if link == true
102
80
  # link and linked text is present else leave col text empty
103
81
  value = (!value.blank? && !link.blank?) ? @template.link_to(value, link) : ''
104
82
  end
105
-
106
- # If row_link option is set, then link to the current object
107
- if row_link = options.delete(:row_link)
108
- row_link = object if row_link == true
109
- value = @template.link_to(value, row_link) unless value.blank?
110
-
111
- # Set a css class for the <td>, so it can be found via JavaScript
112
- # and an onclick-event can be installed (TODO)
113
- td_options.merge!(:class => 'row_link')
114
- end
115
- @template.capture_haml do
116
- @template.haml_tag(:td, value.to_s, td_options)
117
- end
83
+ "<td #{ to_attr(td_options) }>#{value.to_s}</td>".html_safe
118
84
  end # case mode
119
85
  end
120
86
 
@@ -126,36 +92,27 @@ module KingList
126
92
  # = action_icon :edit, edit_path(person)
127
93
  # = action_icon :delete, destroy_path(person)
128
94
  def action_column(options={}, &block)
129
- self.current_column_number += 1
130
-
131
95
  case mode
132
- when :counter
133
- self.number_of_columns ||= 0
134
- self.number_of_columns += 1
135
- nil
136
96
  when :header
137
- options = { :align => :left }
138
- if self.current_column_number == 1
139
- options[:class] = 'first'
140
- elsif self.current_column_number == self.number_of_columns
141
- options[:class] = 'last'
142
- end
143
-
144
- @template.haml_tag :th, options do
145
- @template.haml_concat I18n.t(:'link.actions')
146
- end
97
+ "<th>#{I18n.t(:'link.actions')}</th>".html_safe
147
98
  when :content
148
99
  td_options = options[:td_options] || {}
149
- td_options[:class] = td_options[:class].to_a || []
100
+ td_options[:class] = [td_options[:class]].flatten || []
150
101
  td_options[:class] << 'actions'
151
- @template.haml_tag :td, td_options do
152
- @template.haml_tag :ul, :class => 'actions' do
153
- @template.haml_concat @template.capture_haml(&block)
154
- end
155
- end
102
+ td_options[:class] = td_options[:class].compact.join(' ')
103
+ res = "<td #{ to_attr(td_options) }><ul class='actions'>"
104
+ res << @template.capture(&block)
105
+ res << "</ul></td>"
106
+ res.html_safe
156
107
  end
157
108
  end
158
109
 
110
+ # == Param
111
+ # opts<Hash{Symbol=>String}}>:. options used for html attributes
112
+ def to_attr(opts)
113
+ opts.collect{|k,v| "#{k}='#{v}'" }.join(' ')
114
+ end
115
+
159
116
  end #TableBuilder
160
117
  end # module
161
118
  end # module
@@ -30,7 +30,11 @@ module KingList
30
30
  object = args.first
31
31
  else
32
32
  object = record_or_name
33
- object_name = ActionController::RecordIdentifier.singular_class_name(object)
33
+ object_name = if ActionController::RecordIdentifier.respond_to?(:singular_class_name)
34
+ ActionController::RecordIdentifier.singular_class_name(object) # rails 2
35
+ else #Rails 3
36
+ ActiveModel::Naming.singular(object)
37
+ end
34
38
  end
35
39
 
36
40
  haml_tag :dl, options do
@@ -81,69 +85,56 @@ module KingList
81
85
  # === Usage example:
82
86
  #
83
87
  # Header linking for all, default
84
- # - table_for(@users) do |t, user|
85
- # - t.column :name # with sorting
86
- # - t.column :email
88
+ # = table_for(@users) do |t, user|
89
+ # = t.column :name # with sorting
90
+ # = t.column :email
87
91
  #
88
92
  # Header linking for all, but exclude individual columns from sorting:
89
- # - table_for(@users)do |t, user|
90
- # - t.column :name, :sorting => false # without sorting
91
- # - t.column :last_name
93
+ # = table_for(@users)do |t, user|
94
+ # = t.column :name, :sorting => false # without sorting
95
+ # = t.column :last_name
92
96
  #
93
97
  # NO header linking for all columns:
94
- # - table_for(@users, :sorting => false) do |t, user|
95
- # - t.column :name
96
- # - t.column :email
98
+ # = table_for(@users, :sorting => false) do |t, user|
99
+ # = t.column :name
100
+ # = t.column :email
97
101
  #
98
102
  # No header linking for all, but allow sorting for individual columns:
99
- # - table_for(@users, :sorting => false) do |t, user|
100
- # - t.column :name, :sorting => true # with sorting
101
- # - t.column :last_name
103
+ # = table_for(@users, :sorting => false) do |t, user|
104
+ # = t.column :name, :sorting => true # with sorting
105
+ # = t.column :last_name
102
106
  #
103
107
  def table_for(collection, options={}, html_options={}, &block)
104
108
  return if collection.nil? || collection.empty?
105
-
106
109
  builder = KingList::Builder::Table.new(render_context, collection)
107
110
  # extract options
108
111
  builder.sorting = options.delete(:sorting) != false # default => true
109
-
110
- # First step: Yield the block just for counting the columns
111
- builder.mode = :counter
112
- builder.start_row(collection.first)
113
- yield(builder, builder.current_record)
114
-
115
- haml_tag :table, { :summary => '' }.merge(html_options) do
112
+ capture do
113
+ concat("<table #{ to_attr(html_options) }><thead><tr>".html_safe)
116
114
  # Build header row
117
- haml_tag :thead do
118
- haml_tag :tr do
119
- builder.mode = :header
120
- builder.start_row(collection.first)
121
- yield(builder, builder.current_record)
122
- end
123
- end
124
-
125
- # TODO: Build footer here
126
- # haml_tag :tfoot do
127
- # end
128
-
129
- haml_tag :tbody do
130
- builder.mode = :content
131
- # Build content row for each collection item
132
- collection.each do |c|
133
- tr_options = {}
134
- # zebra styling
135
- tr_options[:class] = render_context.cycle('odd','even')
136
-
137
- haml_tag :tr, tr_options do
138
- builder.start_row(c)
139
- yield(builder, builder.current_record)
140
- end
141
- end
115
+ builder.mode = :header
116
+ builder.current_record = collection.first
117
+ yield(builder, builder.current_record)
118
+ concat("</tr></thead><tbody>".html_safe)
119
+ builder.mode = :content
120
+ # Build content row for each collection item
121
+ collection.each do |c|
122
+ builder.current_record = c
123
+ concat("<tr>".html_safe)
124
+ yield(builder, builder.current_record)
125
+ concat("</tr>".html_safe)
142
126
  end
143
-
127
+ concat( "</tbody></table>".html_safe)
144
128
  end
145
129
  end
146
130
 
131
+ # TODO same in table class
132
+ #== Param
133
+ # opts<Hash{Symbol=>String}}>:. options used for html attributes
134
+ def to_attr(opts)
135
+ opts.collect{|k,v| "#{k}='#{v}'" }.join(' ')
136
+ end
137
+
147
138
  # Show a list of options as ul / li list.
148
139
  # Each actions li gets a special class so image replacement can be done via css
149
140
  # ==== Example
@@ -200,8 +191,8 @@ module KingList
200
191
  # You can set html options for both the li and the a tag
201
192
  #
202
193
  #===Example haml
203
- # action_text _('link.user.edit'), edit_object_path
204
- # action_text _('link.user.edit'), edit_object_path, {li html options}, {a html options :class=>'supercssclass'}
194
+ # action_text t('link.user.edit'), edit_object_path
195
+ # action_text t('link.user.edit'), edit_object_path, {li html options}, {a html options :class=>'supercssclass'}
205
196
  #
206
197
  # => <li>
207
198
  # <a href="/users/edit/12">
@@ -253,7 +244,10 @@ module KingList
253
244
  #
254
245
  def action_button(fieldname, options)
255
246
  render_context.capture_haml do
256
- haml_tag :li, :class=>'form_btn' do
247
+ li_options = options.delete(:li_options) || {}
248
+ li_options[:class] ||= []
249
+ li_options[:class] << " form_btn"
250
+ haml_tag :li, li_options do
257
251
  haml_concat mini_action_form(fieldname, options)
258
252
  end
259
253
  end
@@ -282,8 +276,8 @@ module KingList
282
276
  method_tag +
283
277
  request_token_tag +
284
278
  hidden_tag +
285
- "<button type='submit' name='submit' title='#{options[:title]}' class='#{options[:class]}'><span>#{options[:title]}</span></button>" +
286
- "</div></form>"
279
+ "<button type='submit' name='submit'#{" id='#{options[:id]}'" if options[:id].present?} title='#{options[:title]}' class='#{options[:class]}'><span>#{options[:title]}</span></button>" +
280
+ "</div></form>".html_safe
287
281
  end
288
282
 
289
283
  # Renders a <ol> for a given collection and yields the block for every item
@@ -314,21 +308,24 @@ module KingList
314
308
  # Internal method used by action_text, action_button and action_icon
315
309
  # Directly returns a haml string into the template
316
310
  def action(kind, name_or_title, link_options, li_options={}, html_options={})
317
- render_context.capture_haml do
318
- haml_tag :li, li_options do
319
- case kind
320
- when :icon then haml_concat link_to('', link_options, html_options)
321
- when :text then haml_concat link_to(name_or_title, link_options, html_options)
322
- when :button then haml_concat button_to(name_or_title, link_options)
323
- end
324
- end
311
+
312
+ render_context.capture do
313
+ concat %{ <li #{ to_attr(li_options) }>
314
+ #{ case kind
315
+ when :icon
316
+ link_to('', link_options, html_options)
317
+ when :text
318
+ link_to(name_or_title, link_options, html_options)
319
+ when :button
320
+ button_to(name_or_title, link_options)
321
+ end } </li>}.html_safe
325
322
  end
326
323
  end
327
324
 
328
325
  def render_context
329
- @template || view_context
330
- # if rails < 2 ..
326
+ # rails 2 || rails 3.2
327
+ @template || self
331
328
  end
332
329
 
333
330
  end #ListHelper
334
- end#module
331
+ end#module