king_views 1.0.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 (50) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.rdoc +84 -0
  3. data/Rakefile +31 -0
  4. data/VERSION +1 -0
  5. data/init.rb +3 -0
  6. data/king_form/MIT-LICENSE +20 -0
  7. data/king_form/README.rdoc +64 -0
  8. data/king_form/Rakefile +23 -0
  9. data/king_form/init.rb +1 -0
  10. data/king_form/lib/king_form.rb +19 -0
  11. data/king_form/lib/king_form/builder/base.rb +238 -0
  12. data/king_form/lib/king_form/builder/definition_list.rb +119 -0
  13. data/king_form/lib/king_form/builder/form_fields.rb +333 -0
  14. data/king_form/lib/king_form/builder/form_fields_overrides.rb +146 -0
  15. data/king_form/lib/king_form/builder/labeled.rb +116 -0
  16. data/king_form/lib/king_form/helper.rb +97 -0
  17. data/king_form/lib/king_form/nested_form_helper.rb +61 -0
  18. data/king_form/lib/king_form/overrides.rb +25 -0
  19. data/king_form/tasks/king_forms_tasks.rake +4 -0
  20. data/king_form/test/king_forms_test.rb +8 -0
  21. data/king_form/test/test_helper.rb +3 -0
  22. data/king_format/MIT-LICENSE +20 -0
  23. data/king_format/README.rdoc +20 -0
  24. data/king_format/Rakefile +23 -0
  25. data/king_format/init.rb +1 -0
  26. data/king_format/lib/helpers/date_helper.rb +25 -0
  27. data/king_format/lib/helpers/formatting_helper.rb +108 -0
  28. data/king_format/lib/helpers/money_helper.rb +63 -0
  29. data/king_format/lib/king_format.rb +14 -0
  30. data/king_format/lib/model_mixins/has_date_fields.rb +42 -0
  31. data/king_format/lib/model_mixins/has_money_fields.rb +42 -0
  32. data/king_format/lib/model_mixins/has_percent_fields.rb +34 -0
  33. data/king_format/tasks/king_format_tasks.rake +4 -0
  34. data/king_format/test/king_format_test.rb +8 -0
  35. data/king_format/test/test_helper.rb +3 -0
  36. data/king_list/MIT-LICENSE +20 -0
  37. data/king_list/README.rdoc +21 -0
  38. data/king_list/Rakefile +23 -0
  39. data/king_list/init.rb +1 -0
  40. data/king_list/lib/king_list.rb +18 -0
  41. data/king_list/lib/king_list/app_helper.rb +30 -0
  42. data/king_list/lib/king_list/builder/show.rb +71 -0
  43. data/king_list/lib/king_list/builder/table.rb +166 -0
  44. data/king_list/lib/king_list/list_helper.rb +329 -0
  45. data/king_list/lib/king_list/overrides.rb +6 -0
  46. data/king_list/tasks/king_list_tasks.rake +4 -0
  47. data/king_list/test/king_list_test.rb +8 -0
  48. data/king_list/test/test_helper.rb +3 -0
  49. data/king_views.gemspec +85 -0
  50. metadata +110 -0
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 [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,21 @@
1
+ = KingList
2
+
3
+ King List provides helpers to be used in table listings and detail views.
4
+ It has function for action icons, buttons, actions links and icons with hidden
5
+ forms used to simulate PUT or DELETE requests
6
+
7
+ == Example
8
+ Please read the files in lib/ for further documentation and examples
9
+
10
+ A tabled view
11
+ - table_for(@object) do
12
+ = t.column :firstname
13
+ = t.column :lastname, :sorting=>false
14
+
15
+ A definition list view
16
+ - dl_for current_object do |f|
17
+ = f.show :creator
18
+ = f.show :created_at
19
+ = f.show :updated_at
20
+
21
+ Copyright (c) 2009 Georg Leciejewski, released under the MIT license
@@ -0,0 +1,23 @@
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 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.'
17
+ Rake::RDocTask.new(:rdoc) do |rdoc|
18
+ rdoc.rdoc_dir = 'rdoc'
19
+ rdoc.title = 'KingList'
20
+ rdoc.options << '--line-numbers' << '--inline-source'
21
+ rdoc.rdoc_files.include('README')
22
+ rdoc.rdoc_files.include('lib/**/*.rb')
23
+ end
@@ -0,0 +1 @@
1
+ require "#{File.dirname(__FILE__)}/lib/king_list"
@@ -0,0 +1,18 @@
1
+ # KingList
2
+ # You need:
3
+ # KingFormat Plugin for the table helper
4
+ # - haml
5
+ # - I18n
6
+ $LOAD_PATH << File.expand_path(File.dirname(__FILE__))
7
+ require "king_list/overrides"
8
+ require "king_list/list_helper"
9
+ require "king_list/app_helper"
10
+ require "king_list/builder/table"
11
+ require "king_list/builder/show"
12
+
13
+
14
+ # extend AC with our helper module
15
+ ActionController::Base.helper KingList::ListHelper
16
+
17
+ # Helper Functions used in application controller, which should be extracted a little more
18
+ ActionController::Base.helper KingList::AppHelper
@@ -0,0 +1,30 @@
1
+ module KingList
2
+ # Functions in here are only used by the table helper. Those should be moved
3
+ # to a more general place or an own king view helper
4
+ module AppHelper
5
+ # Returns the "real" (in URL visible) parameters of the current URL. That means all but the keys "action" and "controller"
6
+ def visible_params
7
+ @visible_params ||= params.dup.delete_if{|key,value| [:action, :controller].include?(key.to_sym)}
8
+ end
9
+
10
+ # Change some params of the current URL (and preserve all others)
11
+ # Example:
12
+ # If the current URL is
13
+ # /clients?filter[letter]=T&filter[tags]=abc&mode=cards
14
+ # and you call:
15
+ # change_params(:mode => 'list')
16
+ # The result is:
17
+ # => /clients?filter[letter]=T&filter[tags]=abc&mode=list
18
+ #
19
+ # Attention, this method uses deep_merge, so it works recursive.
20
+ # See this example: If you call
21
+ # change_params(:filter => { :letter => 'S' })
22
+ # you get
23
+ # => /clients?filter[letter]=S&filter[tags]=abc&mode=list
24
+ # Beware that filter[tags] is NOT removed!
25
+ def change_params(options={})
26
+ visible_params.deep_merge(options)
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,71 @@
1
+ module KingList
2
+ module Builder
3
+ class Show
4
+
5
+ def initialize(object_name, object, template)
6
+ @object_name = object_name
7
+ @object = object
8
+ @template = template
9
+ end
10
+
11
+ #
12
+ # ==== Parameter
13
+ # field_name<Symbol>:: The name of the field for the current object
14
+ # options<Hash{:Symbol=>String}>:: A bunch of options to customize the output
15
+ #
16
+ # ==== Options hash:
17
+ # :object => record. If not set the current_current is used
18
+ # :value => cell content (if not set, it will be determined by object.field_name)
19
+ # :link => if set, the value is placed in a link_to
20
+ # :caption => text for dt-tag. If not set, the title is created automaticaly
21
+ #
22
+ # === Example haml
23
+ # = f.show :created_at
24
+ # = f.show :caption => 'Calculated', :value => 39.80
25
+ #
26
+ # valid html options will be applied to both dt and dd
27
+ # options[:class] =>will be applied to dt and dd
28
+ #
29
+ # TODO:
30
+ # rename :caption to :title .. if it does not conflict
31
+ def show(field_name, options={})
32
+ if field_name.is_a?(Hash) && options.empty? # Short call without field_name
33
+ options = field_name
34
+ field_name = nil
35
+
36
+ # Value and caption are needed
37
+ raise ArgumentError unless options.has_key?(:caption)
38
+ raise ArgumentError unless options.has_key?(:value)
39
+ end
40
+
41
+ # Use given object or current_record as default
42
+ if options.has_key?(:object)
43
+ object = options.delete(:object)
44
+ else
45
+ object = @object
46
+ end
47
+
48
+ # Use given caption or translate column title
49
+ caption = options.delete(:caption) || object.class.human_attribute_name(field_name.to_s)
50
+
51
+ # Use given value or take formatted value as default
52
+ value = options.delete(:value) || @template.formatted_value(object, field_name) || '&nbsp;'
53
+
54
+ # if link option is set, then link to this object
55
+ if link = options.delete(:link)
56
+ value = @template.link_to(value, link)
57
+ end
58
+
59
+ # Against HTML validity warnings
60
+ caption = '&nbsp;' if caption.blank?
61
+ value = '&nbsp;' if value.blank?
62
+
63
+ @template.capture_haml do
64
+ @template.haml_tag :dt, caption, options
65
+ @template.haml_tag :dd, value, options
66
+ end
67
+ end
68
+
69
+ end #class
70
+ end # module
71
+ end # module
@@ -0,0 +1,166 @@
1
+ module KingList
2
+ module Builder
3
+ class Table
4
+
5
+ attr_accessor :mode, :current_record, :current_column_number, :number_of_columns, :sorting
6
+
7
+ def initialize(template, collection, &block)
8
+ @template = template
9
+ @collection = collection
10
+ end
11
+
12
+ def start_row(data)
13
+ self.current_column_number = 0
14
+ self.current_record = data
15
+ end
16
+
17
+ # Build a column for a table
18
+ #
19
+ # ==== Parameter
20
+ # field_name<Symbol>:: Name of the object attribute (db column) to show in this column
21
+ # options<Hash{Hash, Symbol=>String}>:: A bunch of options to customize the th, td or content of the column
22
+ #
23
+ # ==== Options hash:
24
+ # :object => The record to use. If not set the current_object is used
25
+ # :value => cell content (if not set, it will be determined by calling field_name on object/current_record) => @client.name
26
+ # :link => if set, the value is wrapped in a link_to with the given link (if TRUE, the current object is used)
27
+ # :row_link => if set, the value is wrapped in a link_to with the given link (if TRUE, the current object is used)
28
+ # :title => text for column title. If not set, the title is created automaticaly
29
+ # :sort_fields => optional fields for order_by (if the column field does not exist in the database)
30
+ # :sorting => false to prevent sorting on this column
31
+ # :th_options{Symbol=>String}:: options for the <th>
32
+ # :class:: the class to set on the th
33
+ # :td_options{Symbol=>String}:: options for the <td>
34
+ # :class:: the class to set on the th
35
+ # :align => classes used for alignment. Values are :left or :right
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] || {}
40
+
41
+ # Use given object from options (or current_record as default)
42
+ object = options.has_key?(:object) ? options.delete(:object) : current_record
43
+
44
+ # Cell alignment
45
+ align = options.delete(:align)
46
+ (th_options[:class] ||= '') << " #{align}" if align == :right
47
+ (td_options[:class] ||= '') << " #{align}" if align == :right
48
+
49
+ self.current_column_number += 1
50
+
51
+ case mode
52
+ when :counter
53
+ self.number_of_columns ||= 0
54
+ self.number_of_columns += 1
55
+ nil
56
+
57
+ when :header
58
+ # Take option or translate column title
59
+ title_text = options[:title] || object.class.human_attribute_name(field_name.to_s)
60
+
61
+ # whole table has sorting enabled and current column has NOT :sorting=>false
62
+ # => put sorting link into header
63
+ if sorting && (options.delete(:sorting) != false)
64
+ # Use given sort_fields or try to detect them automatic
65
+ sort_fields = options.delete(:sort_fields) || object.class.table_name + '.' + field_name.to_s
66
+ # Convert to comma separated string if it is an array
67
+ sort_fields = sort_fields.join(',') if sort_fields.is_a?(Array)
68
+ # Swap ASC/DESC on every click of the same column title
69
+ sort = (@template.params[:sort] == "ASC") ? 'DESC' : 'ASC'
70
+ # Now build the title
71
+ title = @template.link_to(title_text, @template.change_params(:sort_by => sort_fields, :sort => sort))
72
+ # if current sorting use class for css up/down image
73
+ if @template.params[:sort_by] == sort_fields
74
+ (th_options[:class] ||= '') << ( sort=='DESC' ? ' sortup' : ' sortdown')
75
+ end
76
+ else
77
+ # otherwise just plain text (no sorting link)
78
+ title = title_text
79
+ end
80
+ #mark the first and last columns with css classes
81
+ if self.current_column_number == 1
82
+ (th_options[:class] ||= '') << ' first'
83
+ elsif self.current_column_number == self.number_of_columns
84
+ (th_options[:class] ||= '') << ' last'
85
+ end
86
+ @template.capture_haml do
87
+ @template.haml_tag(:th, title.to_s, th_options)
88
+ end
89
+
90
+
91
+ when :content
92
+ # Use given value (or formatted value as default)
93
+ value = options.delete(:value) || @template.formatted_value(object, field_name, value)
94
+
95
+ # If link option is set, then link to this
96
+ #
97
+ # ===Example
98
+ #
99
+ # :link => true : uses current object show link
100
+ #
101
+ # :link => nil or blank no linking
102
+ #
103
+ if link = options.delete(:link)
104
+ #link to current_oject if true given
105
+ link = object if link == true
106
+ if (!value.blank?) && (!link.blank?) #link and linked text is present
107
+ value = @template.link_to(value, link)
108
+ else #leave col text empty
109
+ value = ''
110
+ end
111
+ end
112
+
113
+ # If row_link option is set, then link to the current object
114
+ if row_link = options.delete(:row_link)
115
+ row_link = object if row_link == true
116
+ value = @template.link_to(value, row_link) unless value.blank?
117
+
118
+ # Set a css class for the <td>, so it can be found via JavaScript
119
+ # and an onclick-event can be installed (TODO)
120
+ td_options.merge!(:class => 'row_link')
121
+ end
122
+ @template.capture_haml do
123
+ @template.haml_tag(:td, value.to_s, td_options)
124
+ end
125
+ # @template.haml_concat
126
+ end # case mode
127
+ end
128
+
129
+ #build a table column which holds action links (edit/del/show/..) for each record
130
+ #is used for table listings ex. on index pages
131
+ #get a block containing multiple #action_
132
+ # ===Example haml
133
+ # - t.action_column do
134
+ # = action_icon :edit, edit_path(person)
135
+ # = action_icon :delete, destroy_path(person)
136
+ def action_column(options={}, &block)
137
+ self.current_column_number += 1
138
+
139
+ case mode
140
+ when :counter
141
+ self.number_of_columns ||= 0
142
+ self.number_of_columns += 1
143
+ nil
144
+ when :header
145
+ options = { :align => :left }
146
+ if self.current_column_number == 1
147
+ options[:class] = 'first'
148
+ elsif self.current_column_number == self.number_of_columns
149
+ options[:class] = 'last'
150
+ end
151
+
152
+ @template.haml_tag :th, options do
153
+ @template.haml_concat I18n.t(:'link.actions')
154
+ end
155
+ when :content
156
+ @template.haml_tag :td, :class => 'actions' do
157
+ @template.haml_tag :ul, :class => 'actions' do
158
+ @template.haml_concat @template.capture_haml(&block)
159
+ end
160
+ end
161
+ end
162
+ end
163
+
164
+ end #TableBuilder
165
+ end # module
166
+ end # module
@@ -0,0 +1,329 @@
1
+ module KingList
2
+ # The List Helper aides in lists anddetail views by providing helpers for:
3
+ # tables, action icons, action buttons and action links, definition list helper
4
+ module ListHelper
5
+
6
+ # Build a definition list(dl/dt/dd) for a collection
7
+ # Usage examples:
8
+ # - dl_for(client)
9
+ # - dl_for(:client, my_client_object)
10
+ # === Example haml
11
+ # - dl_for(current_object) do |f|
12
+ # - f.show :first_name
13
+ # - f.show :last_name
14
+ #
15
+ # => <dl>
16
+ # <dt>Firstname</dt>
17
+ # <dd>Otto</dd>
18
+ # <dt>Lastname</dt>
19
+ # <dd>Bismark</dd>
20
+ # </dl>
21
+ #
22
+ # Parameters are like "form_for"
23
+ def dl_for(record_or_name, *args)
24
+ raise ArgumentError, "Missing block" unless block_given?
25
+
26
+ options = args.extract_options!
27
+ case record_or_name
28
+ when String, Symbol
29
+ object_name = record_or_name
30
+ object = args.first
31
+ else
32
+ object = record_or_name
33
+ object_name = ActionController::RecordIdentifier.singular_class_name(object)
34
+ end
35
+
36
+ haml_tag :dl, options do
37
+ yield KingList::Builder::Show.new(object_name, object, @template)
38
+ end
39
+ end
40
+
41
+ # Create a section
42
+ # A section is a group of related object information and
43
+ # generates a fieldset with optional legend
44
+ #
45
+ # === Example haml
46
+ # - section :caption => _('legend.user.details'), :class => 'my_css_class' do
47
+ # %p= "This is the content"
48
+ #
49
+ # => # <fieldset>
50
+ # <legend>User Details</legend>
51
+ # <p>This is the content</p>
52
+ # </fieldset>
53
+ #
54
+ def section(options = {}, &block)
55
+ # Short form of usage
56
+ if options.is_a?(String)
57
+ caption = options
58
+ options = {}
59
+ end
60
+
61
+ caption ||= options.delete(:caption)
62
+
63
+ @template.haml_tag :fieldset, options do
64
+ @template.haml_tag :legend, caption unless caption.blank?
65
+ @template.haml_concat @template.capture_haml(&block)
66
+ end
67
+ end
68
+
69
+ # Create a div for form actions
70
+ def actions(options = {}, &block)
71
+ @template.haml_tag :div, options.merge(:class => 'form_actions') do
72
+ @template.haml_concat @template.capture_haml(&block)
73
+ end
74
+ end
75
+
76
+ # Build a table-tag for a collection
77
+ #
78
+ # Available option keys:
79
+ # :sorting => Enable/Disable sorting for ALL columns (default is true)
80
+ #
81
+ # === Usage example:
82
+ #
83
+ # Header linking for all, default
84
+ # - table_for(@users) do |t, user|
85
+ # - t.column :name # with sorting
86
+ # - t.column :email # with sorting
87
+ #
88
+ # 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 # with sorting
92
+ #
93
+ # NO header linking for all columns:
94
+ # - table_for(@users, :sorting => false) do |t, user|
95
+ # - t.column :name # without sorting
96
+ # - t.column :email # without sorting
97
+ #
98
+ # 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 # without sorting
102
+ #
103
+ def table_for(collection, options={}, html_options={}, &block)
104
+ return if collection.nil? || collection.empty?
105
+
106
+ builder = KingList::Builder::Table.new(@template, collection)
107
+ # extract options
108
+ 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
116
+ # 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] = @template.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
142
+ end
143
+
144
+ end
145
+ end
146
+
147
+ # Show a list of options as ul / li list.
148
+ # Each actions li gets a special class so image replacement can be done via css
149
+ # ==== Example
150
+ # - action_group do
151
+ # = action_icon :edit, edit_object_path(client)
152
+ # = action_icon :invoice_add, new_client_invoice_path(client), :title => 'New Invoice'
153
+ # = action_text t(:'web_templates.new'), new_object_path,{},{ :class=>'btn_add'}
154
+ # # <ul class="actions">
155
+ # <li class="button delete">
156
+ # <a href="delete/id">delete</a>
157
+ def action_group(caption=nil, options={}, &block)
158
+ if caption && !caption.empty?
159
+ haml_tag :span, caption, { :class => 'caption' }
160
+ end
161
+
162
+ options[:class] ||= 'actions'
163
+ haml_tag :ul, options do
164
+ haml_concat capture_haml(&block)
165
+ end
166
+ end
167
+
168
+ # Renders a <li> with a link shown as icon
169
+ # The link text is hidden via css image replacement and only an icon is shown
170
+ #
171
+ # ==== Example
172
+ # action_icon :show, show_user(user), :title => "Show User details"
173
+ # => <li class="show"><a href="/users/show" title="Show User details"><span>show</span></a></li>
174
+ # ==== Parameter
175
+ # name<String>:: The name of the action which is taken in the translated title,
176
+ # and li class (if no custom class is present in li_options )
177
+ # li_options<Hash{Symbol=>String}>:: Options for the li-element
178
+ # link_options<Hash>:: Options passed on to rails link_to method #
179
+ # html_options<Hash>:: Options passed on to rails link_to method
180
+ # ==== Options li_options
181
+ # :title - the html title tag for the li
182
+ # :class - the html class tag for the li
183
+ def action_icon(name, link_options={}, li_options={}, html_options={})
184
+ li_options[:title] ||= case name
185
+ # Some known names with their titles
186
+ when :edit then t(:'link.edit')
187
+ when :pdf then t(:'link.pdf')
188
+ when :show then t(:'link.show')
189
+ when :delete then t(:'link.delete')
190
+ when :copy then t(:'link.copy')
191
+ when :comment then t(:'link.comment')
192
+ when :send_email then t(:'link.send_email')
193
+ end
194
+ (li_options[:class] ||= '') << " icon #{name}"
195
+
196
+ action :icon, name, link_options, li_options, html_options
197
+ end
198
+
199
+ # Renders a <li> with a link shown as text
200
+ # You can set html options for both the li and the a tag
201
+ #
202
+ #===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'}
205
+ #
206
+ # => <li>
207
+ # <a href="/users/edit/12">
208
+ # link.user.edit
209
+ # </a>
210
+ # </li>
211
+ #
212
+ def action_text(title, link_options, li_options={}, html_options={})
213
+ # Prepare the css-class for the <li>
214
+ li_options[:class] ||= ''
215
+ li_options[:class] << ' active' if li_options.delete(:active)
216
+
217
+ #kill class attribute if still empty
218
+ li_options.delete(:class) if li_options[:class].empty?
219
+ action :text, title, link_options, li_options, html_options
220
+ end
221
+
222
+ # Renders a <li> with a button that will submit a form to a given url.
223
+ # This allows to make POST/PUT/DELETE request instead of using a link which triggers a GET.
224
+ #
225
+ # The button tags name attribute will be set to the <tt>name</tt> paramter followed by
226
+ # either the <tt>:id</tt> url_for_options value or a <tt>:number</tt> option either is
227
+ # available.
228
+ #
229
+ # ==== Parameters
230
+ # fieldname<String>:: the name attribute of the hidden form field f.ex. 'status' or 'invoice[status]'
231
+ # options<Hash>:: a couple of options explained further on
232
+ #
233
+ # ==== Options
234
+ # :method<Symbol>::form request method: :post / :put / :delete
235
+ # :url<String>:: The url the form is submitted to
236
+ # :title<String>::Button title and text
237
+ # :value<String>::the hidden field value
238
+ # :class<String>::button class
239
+ #
240
+ # ==== Example
241
+ # = action_button 'order_status', {:value=>'open', :title=> "Change Status to open", :method => :put}
242
+ #
243
+ #
244
+ # ==== Returns
245
+ # <form>
246
+ # <div>
247
+ # <input type="hidden" value="put" name="_method"/>
248
+ # <input type="hidden" value="939f3c1dc225bcaa2e5c2bd88910537901dc19d6" name="authenticity_token"/>
249
+ # <input type="hidden" value="open" name="order_status"/>
250
+ # <button type='submit' class="some_class" title="Change Status to open">Change Status to open</button>
251
+ # </div>
252
+ # </form>
253
+ #
254
+ def action_button(fieldname, options)
255
+ @template.capture_haml do
256
+ haml_tag :li, :class=>'form_btn' do
257
+ haml_concat mini_action_form(fieldname, options)
258
+ end
259
+ end
260
+ end
261
+ def action_link(fieldname, options)
262
+ haml_concat mini_action_form(fieldname, options)
263
+ end
264
+
265
+ def mini_action_form(fieldname, options)
266
+ method_tag = ''
267
+ if (method = options.delete(:method)) && %w{put delete}.include?(method.to_s)
268
+ method_tag = tag('input', :type => 'hidden', :name => '_method', :value => method.to_s)
269
+ end
270
+
271
+ form_method = method.to_s == 'get' ? 'get' : 'post'
272
+
273
+ request_token_tag = ''
274
+ if form_method == 'post' && protect_against_forgery?
275
+ request_token_tag = tag(:input, :type => "hidden", :name => request_forgery_protection_token.to_s, :value => form_authenticity_token)
276
+ end
277
+
278
+ hidden_tag = ''
279
+ hidden_tag = tag(:input, :type => "hidden", :name =>fieldname, :value => options[:value]) unless options[:value].blank?
280
+
281
+ "<form method=\"#{form_method}\" action=\"#{escape_once options[:url]}\"><div>" +
282
+ method_tag +
283
+ request_token_tag +
284
+ hidden_tag +
285
+ "<button type='submit' name='submit' title='#{options[:title]}' class='#{options[:class]}'><span>#{options[:title]}</span></button>" +
286
+ "</div></form>"
287
+ end
288
+
289
+ # Renders a <ol> for a given collection and yields the block for every item
290
+ # Options:
291
+ # :descending: if true, numbering is reversed (defaults to false)
292
+ def ordered_list_for(collection, options={}, &block)
293
+ if collection.nil? || collection.empty?
294
+ haml_tag :p, _('list.empty')
295
+ return
296
+ end
297
+
298
+ descending = options.delete(:descending)
299
+
300
+ haml_tag :ol, options do
301
+ collection.each_with_index do |c,i|
302
+ li_options = {}
303
+ li_options[:class] = @template.cycle('odd','even')
304
+ li_options[:value] = collection.length - i if descending
305
+ haml_tag :li, li_options do
306
+ yield(c)
307
+ end
308
+ end
309
+ end
310
+ end
311
+
312
+ private
313
+
314
+ # Internal method used by action_text, action_button and action_icon
315
+ # Directly returns a haml string into the template
316
+ def action(kind, name_or_title, link_options, li_options={}, html_options={})
317
+ @template.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
325
+ end
326
+ end
327
+
328
+ end #ListHelper
329
+ end#module