king_views 1.0.0

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