king_views 1.1.6 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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