usefull_table 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (28) hide show
  1. data/CHANGELOG.md +12 -0
  2. data/Gemfile +27 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +234 -0
  5. data/Rakefile +31 -0
  6. data/app/controllers/usefull_table/table_controller.rb +34 -0
  7. data/app/helpers/usefull_table_helper.rb +323 -0
  8. data/app/views/usefull_table/table/create.xlsx.maker +17 -0
  9. data/config/routes.rb +8 -0
  10. data/lib/generators/usefull_table/install/install_generator.rb +47 -0
  11. data/lib/generators/usefull_table/install/templates/config/locales/usefull_table.it.yml +42 -0
  12. data/lib/generators/usefull_table/install/templates/public/images/usefull_table_destroy.png +0 -0
  13. data/lib/generators/usefull_table/install/templates/public/images/usefull_table_download.png +0 -0
  14. data/lib/generators/usefull_table/install/templates/public/images/usefull_table_edit.png +0 -0
  15. data/lib/generators/usefull_table/install/templates/public/images/usefull_table_false.png +0 -0
  16. data/lib/generators/usefull_table/install/templates/public/images/usefull_table_show.png +0 -0
  17. data/lib/generators/usefull_table/install/templates/public/images/usefull_table_true.png +0 -0
  18. data/lib/generators/usefull_table/install/templates/public/stylesheets/usefull_table.css +101 -0
  19. data/lib/generators/usefull_table/scaffold/scaffold_generator.rb +12 -0
  20. data/lib/generators/usefull_table/scaffold/templates/lib/templates/erb/scaffold/index.html.erb +15 -0
  21. data/lib/generators/usefull_table/scaffold/templates/lib/templates/erb/scaffold/show.html.erb +12 -0
  22. data/lib/generators/usefull_table/scaffold/templates/lib/templates/rails/scaffold_controller/controller.rb +84 -0
  23. data/lib/usefull_table/engine.rb +17 -0
  24. data/lib/usefull_table/exceptions.rb +17 -0
  25. data/lib/usefull_table/table_builder.rb +522 -0
  26. data/lib/usefull_table/version.rb +3 -0
  27. data/lib/usefull_table.rb +13 -0
  28. metadata +123 -0
data/CHANGELOG.md ADDED
@@ -0,0 +1,12 @@
1
+ ToDo
2
+ - Autodetection in table data of: boolean and 'true' and 'false'. To render with red and green traffic-light image.
3
+ - Add tip to cell
4
+ - Add option :excel => false to column to remove from excel export
5
+ - Add option [:export][:type] => :xls, :xlsx, :pdf, :all, [:xls, :xlsx]
6
+
7
+ BugToFix
8
+ 1.0.1 (June 29, 2012)
9
+ - First working release
10
+
11
+ 0.1.0 (June 18, 2012)
12
+ - first Release
data/Gemfile ADDED
@@ -0,0 +1,27 @@
1
+ source "http://rubygems.org"
2
+
3
+ #remove in production
4
+ #gem "acts_as_xls", :path => "/home/apps/rails_apps/gems/acts_as_xls"
5
+ #gem "acts_as_monitor", :path => "/home/apps/rails_apps/gems/acts_as_monitor"
6
+ gem "rails", "3.0.9"
7
+ #gem "in_place_editing"
8
+
9
+ group :development do
10
+ gem "acts_as_monitor", :path => "/home/apps/rails_apps/gems/acts_as_monitor"
11
+ gem "acts_as_xls", :path => "/home/apps/rails_apps/gems/acts_as_xls"
12
+ gem "meta_search"
13
+ gem "will_paginate"
14
+ gem "ruby-debug"
15
+ end
16
+
17
+ group :test do
18
+ gem "acts_as_monitor", :path => "/home/apps/rails_apps/gems/acts_as_monitor"
19
+ gem "acts_as_xls", :path => "/home/apps/rails_apps/gems/acts_as_xls"
20
+ gem "capybara", ">= 0.4.0"
21
+ gem "meta_search"
22
+ gem "will_paginate"
23
+ gem "ruby-debug"
24
+ end
25
+
26
+
27
+ gemspec
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2012 YOURNAME
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.
data/README.rdoc ADDED
@@ -0,0 +1,234 @@
1
+ =UsefullTable
2
+ table_for generate a full-optionals table, with excel export, columns ordering, links, inline edit and monitoring (ActsAsMonitor https://github.com/skylord73/acts_as_monitor)
3
+ but don't warry because a rich set of defaults, make its use very simple
4
+
5
+ for a working sample please refer to test/dummy
6
+
7
+ ==Setup
8
+ Add this line to your application's Gemfile:
9
+ gem 'usefull_table'
10
+
11
+ then execute
12
+ $ bundle install
13
+
14
+ or install it yourself as:
15
+ $ sudo gem install usefull_table
16
+
17
+ copy icons, javascript and stylesheets:
18
+ $ rails g usefull_table:install
19
+
20
+ modify default scaffold to use usefull_table, meta_search and will_paginate (controller and index.html.erb):
21
+ $ rails g usefull_table:scaffold
22
+
23
+
24
+ ==Usage
25
+ Write few lines in your controller
26
+ app/controllers/home_controller.rb
27
+ def index
28
+ @search = Item.search(params[:search])
29
+ ...
30
+ respond_to do |format|
31
+ format.html { @items = @search.paginate(:page => params[:page]) }
32
+ end
33
+ ...
34
+ end
35
+
36
+ and in your view
37
+ app/views/home/my_view.html.erb
38
+ <%= table_for @items, @search, options = {} do |t| %>
39
+ <% t.show :url => Proc.new { |item| item_path(item)} %>
40
+ <% t.edit :url => Proc.new { |item| edit_item_path(item)}%>
41
+ <% t.destroy :url => Proc.new { |item| item_path(item)}, :link_options => {:method => delete, :confirm => "are you sure?"} %>
42
+ <% t.download :url => Proc.new { |item| download_item_path(item)} %>
43
+ <% t.col :name %>
44
+ <% t.col "user.name" %>
45
+ <% t.status %>
46
+ <% end %>
47
+
48
+ ==Options
49
+ default values in *bold*
50
+
51
+ ===Paginator
52
+ options[:paginator][:visible] = *true* | false _note_: false if @items not present
53
+ options[:paginator][:class] = *"usefull_table_paginator"*
54
+
55
+ ===Container
56
+ options[:html] = *{:class => "usefull_table_container"}*
57
+
58
+ ===Excel
59
+ options[:export][:visible] = *true* | false
60
+ options[:export][:filter] = *true* | false _note:_ false if @search not present
61
+ options[:export][:human] = *true* | false
62
+ options[:export][:worksheet] = *object.class.name.gsub(/::/,"#")* _note:_ class name with namespace separator #
63
+ options[:export][:url] = Custom Url and format
64
+
65
+ ===Table
66
+ options[:table][:div_html] = *{:class => "usefull_table"}*
67
+ options[:table][:header_html] = *{:class => "first_row"}*
68
+ options[:table][:header_type] = *:sort* _note:_ :human if @search not present (no sorting possible)
69
+ :plain bare column name from ActiveRecord
70
+ :human column name humanized by ActiveRecord
71
+ :nil no column name
72
+
73
+ ==Localization
74
+ Uses standard ActiveRecord localization to render tables and columns names
75
+ it:
76
+ activerecord:
77
+ attributes:
78
+ item:
79
+ name: Name
80
+ type: Type
81
+ user:
82
+ name: Name
83
+ models:
84
+ item:
85
+ one: Item
86
+ other: Items
87
+ user:
88
+ one: User
89
+ other: Users
90
+
91
+ #config/usefull_table.it.yml
92
+ it:
93
+ usefull_table:
94
+ submit_excel: Excel
95
+ header_error: Errore
96
+ body_error: Errore
97
+
98
+ icons:
99
+ show: "usefull_table_show.png"
100
+ edit: "usefull_table_edit.png"
101
+ destroy: "usefull_table_destroy.png"
102
+ download: "usefull_table_download.png"
103
+
104
+ =Column Types
105
+ ==col
106
+ Render column value
107
+
108
+ ===Usage
109
+ <% t.col :name %> #render column :name ( t.col "name" is ok)
110
+ <% t.col "user.name" %> #render column name of the user collection in item (item.user.name)
111
+
112
+ ===Options
113
+
114
+ :header_type =>
115
+ - *:sort* #Header is MetaSearch#sort_link of columns_name
116
+ - :human #Header is plain text humanized with ActiveRecord column name
117
+ - :nil #No header
118
+
119
+ :label =>
120
+ - "Custom Name" #plain text without localization
121
+ - :custom_name #localized text in lazy context (.)
122
+
123
+ :data_type => #default get class name from object to render
124
+ - :Date
125
+ - :Time
126
+ - :DateTime
127
+ - :Currency
128
+ - :Bool #Transform value in boolean
129
+ - :Bool_reverse #Transform vale in boolean and reverse the vale
130
+
131
+ :url =>
132
+ - "static_path"
133
+ - Proc #Proc expose the object instance of the current row
134
+
135
+ :inline =>
136
+ - *false*
137
+ - true #enable inline editing for the column, works also with nested fields (no controller add-on required)
138
+
139
+ ==label
140
+ Render static label
141
+
142
+ ===Usage
143
+ <% t.label object %> #render object.inspect
144
+ <% t.label Proc.new {|item| item.name.capitalize} %> #Evaluate proc with item instance of the corresponding row
145
+
146
+ ==monitor
147
+ Render a tri-state icon to monitor model status
148
+ * Red : Error
149
+ * Yellow: Warning
150
+ * Green: Status ok
151
+
152
+ Enable only if acts_as_monitor gem is required (https://github.com/skylord73/acts_as_monitor)
153
+
154
+ ==Usage
155
+ <% t.monitor %>
156
+
157
+ Clicking the icon you get the comlete problem description pushed by Ajaxs script (no page reload)
158
+
159
+ ==link
160
+ Create a link to something, using Icons or CustomText
161
+
162
+ ===Usage
163
+ <% t.show :url => Proc.new {|object| home_path(object) }"%>
164
+ <% t.destroy :url => Proc.new {|object| home_path(object) }"%>
165
+ <% t.link :name => "Custom Link", :url => Proc.new {|object| my_link_home_path(object) }"%> #text link (Custom Link) to url
166
+ <% t.link :name => "Custom Link", :body_typ => :icon, :url => Proc.new {|object| my_link_home_path(object) }"%> #icon link with icon name = usefull_table_cusom_link.png or localization in usefull_table.icons.custom_link
167
+
168
+ ===Options
169
+
170
+ :url =>
171
+ - Proc
172
+ - "my_custom_static_url"
173
+
174
+ :label =>
175
+ - :show_doc #localized in lazy contest (.)
176
+ - "Show Doc" #printed without localization
177
+
178
+ :link_options =>
179
+ - *nil*
180
+ - {:method => delete, :confirm => "sicuro?"} if name == :destroy
181
+
182
+ :name =>
183
+ - :symbol
184
+ - "string" #if method_name == :link the name is used as link_text (localized if symbol), ignored elsewhere
185
+
186
+ ==bool
187
+ Create a boolean value using images to represent status.
188
+ Images name can be changed in locales
189
+
190
+ ===Usage
191
+ <% t.bool :name %>
192
+ <% t.bool :name, :reverse => true%>
193
+
194
+ ===Options
195
+ :header_type =>
196
+ - *:sort* #Header is MetaSearch#sort_link of columns_name
197
+ - :human #Header is plain text humanized with ActiveRecord column name
198
+ - :nil #No header
199
+
200
+ :label =>
201
+ - "Custom Name" #plain text without localization in header
202
+ - :custom_name #localized text in lazy context (.) in header
203
+
204
+ :url =>
205
+ - "my_custom_static_url"
206
+ - Proc #Proc expose the object instance of the current row
207
+
208
+ :reverse =>
209
+ - *false*
210
+ - true #reverse boolean value
211
+
212
+ ==Personalization
213
+
214
+ Feel free to modify the following files:
215
+
216
+ - public/stylesheets/usefull_table.css
217
+ - config/locales/usefull_table.it.yml
218
+
219
+ ==Contributing
220
+
221
+ 1. Fork it
222
+ 2. Create your feature branch (git checkout -b my-new-feature)
223
+ 3. Commit your changes (git commit -am 'Added some feature')
224
+ 4. Push to the branch (git push origin my-new-feature)
225
+ 5. Create new Pull Request
226
+
227
+ ==Thanks
228
+
229
+ Many thanks to :
230
+ - MetaSearch
231
+ - WillPaginate
232
+ - Spreadsheet
233
+ - Axlsx
234
+
data/Rakefile ADDED
@@ -0,0 +1,31 @@
1
+ # encoding: UTF-8
2
+ require 'rubygems'
3
+ begin
4
+ require 'bundler/setup'
5
+ require "bundler/gem_tasks"
6
+ rescue LoadError
7
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
8
+ end
9
+
10
+ require 'rake'
11
+ require 'rake/testtask'
12
+ require 'rdoc/task'
13
+
14
+
15
+
16
+ Rake::TestTask.new(:test) do |t|
17
+ t.libs << 'lib'
18
+ t.libs << 'test'
19
+ t.pattern = 'test/**/*_test.rb'
20
+ t.verbose = false
21
+ end
22
+
23
+ task :default => :test
24
+
25
+ Rake::RDocTask.new(:rdoc) do |rdoc|
26
+ rdoc.rdoc_dir = 'rdoc'
27
+ rdoc.title = 'UsefullTable'
28
+ rdoc.options << '--line-numbers' << '--inline-source'
29
+ rdoc.rdoc_files.include('README.rdoc')
30
+ rdoc.rdoc_files.include('lib/**/*.rb')
31
+ end
@@ -0,0 +1,34 @@
1
+ module UsefullTable
2
+ class TableController < ::ApplicationController
3
+
4
+ def create
5
+ usefull_table = HashWithIndifferentAccess.new(ActiveSupport::JSON.decode(params[:usefull_table]))
6
+ #Rails::logger.info("MonitorsController back=#{usefull_table[:paths].inspect}")
7
+ if usefull_table[:class_name].present?
8
+ if usefull_table[:search].present?
9
+ @object = usefull_table[:class_name].constantize.search(usefull_table[:search]).relation
10
+ else
11
+ @object = usefull_table[:class_name].constantize.all
12
+ end
13
+ @params = usefull_table[:params]
14
+ end
15
+
16
+ respond_to do |format|
17
+ format.html
18
+ format.xlsx { render :xlsx => "create", :template => select_path(usefull_table[:paths],"xlsx.maker") }
19
+ end
20
+ end
21
+
22
+ def update
23
+ #usefull_table = HashWithIndifferentAccess.new(ActiveSupport::JSON.decode(params[:usefull_table]))
24
+ Rails::logger.info("TableController#update params=#{params.inspect}")
25
+ if params[:class_name].present? && params[:attribute_name].present?
26
+ @item = params[:class_name].to_s.camelize.constantize.find(params[:id])
27
+ @item.update_attribute(params[:attribute_name], params[:value])
28
+ render :text => CGI::escapeHTML(@item.send(params[:attribute_name]).to_s)
29
+ end
30
+ end
31
+
32
+
33
+ end
34
+ end
@@ -0,0 +1,323 @@
1
+ module UsefullTableHelper
2
+ #=UsefullTable
3
+ #table_for generate a full-optionals table, with excel export, columns ordering, links, inline edit and monitoring (ActsAsMonitor gem)
4
+ #but don't warry because of a rich set of defaults, make its use very simple
5
+ #
6
+ #==Setup
7
+ #Add this line to your application's Gemfile:
8
+ # gem 'usefull_table'
9
+ #
10
+ #then execute
11
+ # $ bundle install
12
+ #
13
+ #or install it yourself as:
14
+ # $ sudo gem install usefull_table
15
+ #
16
+ #copy icons, javascript and stylesheets:
17
+ # $ rails g usefull_table:install
18
+ #
19
+ #==Usage table_for
20
+ #Write few lines in your controller
21
+ # app/controllers/home_controller.rb
22
+ # def index
23
+ # @search = Item.search(params[:search])
24
+ # ...
25
+ # respond_to do |format|
26
+ # format.html { @items = @search.paginate(:page => params[:page]) }
27
+ # end
28
+ # ...
29
+ # end
30
+ #
31
+ #and in your view
32
+ # app/views/home/my_view.html.erb
33
+ # <%= table_for @items, @search, options = {} do |t| %>
34
+ # <% t.show :url => Proc.new { |item| item_path(item)} %>
35
+ # <% t.edit :url => Proc.new { |item| edit_item_path(item)}%>
36
+ # <% t.destroy :url => Proc.new { |item| item_path(item)}, :link_options => {:method => delete, :confirm => "are you sure?"} %>
37
+ # <% t.download :url => Proc.new { |item| download_item_path(item)} %>
38
+ # <% t.col :name %>
39
+ # <% t.col "user.name" %>
40
+ # <% t.status %>
41
+ # <% end %>
42
+ #
43
+ #==Options
44
+ #default values in *bold*
45
+ #
46
+ #===Paginator
47
+ # options[:paginator][:visible] = *true* | false _note_: false if @items not present
48
+ # options[:paginator][:class] = *"usefull_table_paginator"*
49
+ #
50
+ #===Container
51
+ # options[:html] = *{:class => "usefull_table_container"}*
52
+ #
53
+ #===Excel
54
+ # options[:export][:visible] = *true* | false
55
+ # options[:export][:filter] = *true* | false _note:_ false if @search not present
56
+ # options[:export][:human] = *true* | false
57
+ # options[:export][:worksheet] = *object.class.name.gsub(/::/,"#")* _note:_ class name with namespace separator #
58
+ # options[:export][:url] = custom url
59
+ #===Table
60
+ # options[:table][:div_html] = *{:class => "usefull_table"}*
61
+ # options[:table][:header_html] = *{:class => "first_row"}*
62
+ # options[:table][:header_type] = *:sort* _note:_ :human if @search not present (no sorting possible)
63
+ # :plain bare column name from ActiveRecord
64
+ # :human column name humanized by ActiveRecord
65
+ # :nil no column name
66
+ #
67
+ #==Localization
68
+ #Uses standard ActiveRecord localization to render tables and columns names
69
+ # it:
70
+ # activerecord:
71
+ # attributes:
72
+ # item:
73
+ # name: Name
74
+ # type: Type
75
+ # user:
76
+ # name: Name
77
+ # models:
78
+ # item:
79
+ # one: Item
80
+ # other: Items
81
+ # user:
82
+ # one: User
83
+ # other: Users
84
+ #
85
+ # #config/usefull_table.it.yml
86
+ # it:
87
+ # usefull_table:
88
+ # submit_excel: Excel
89
+ # header_error: Errore
90
+ # body_error: Errore
91
+ #
92
+ # icons:
93
+ # show: "usefull_table_show.png"
94
+ # edit: "usefull_table_edit.png"
95
+ # destroy: "usefull_table_destroy.png"
96
+ # download: "usefull_table_download.png"
97
+ #
98
+ def table_for(obj, *args, &block)
99
+ #Rails::logger.info("table_for START args=#{args.inspect}")
100
+ unless obj.blank?
101
+ search = args.shift if args[0].kind_of?(MetaSearch::Builder)
102
+ #Rails::logger.info("table_for START(1) search=#{search.inspect}")
103
+ options = args.extract_options!
104
+ raise UsefullTable::MissingBlock unless block_given?
105
+
106
+ if obj.kind_of?(MetaSearch::Builder)
107
+ search = obj
108
+ object = obj.relation
109
+ search_attributes = search.search_attributes
110
+ else
111
+ object = obj
112
+ end
113
+
114
+ builder = UsefullTable::TableBuilder.new(object, search, options, self, &block)
115
+ options = builder.options
116
+
117
+ out = ""
118
+ out << monitor_tag_js if options[:monitor][:visible] == true
119
+ out << stylesheet_link_tag('usefull_table.css')
120
+ out << content_tag(:div, options[:html]) do
121
+ ext = ''
122
+ ext << usefull_table_paginator_for(object, options[:paginator])
123
+ ext << usefull_table_export_for(object,search,builder, options[:export])
124
+ ext << usefull_table_for(builder, object, search, options[:table])
125
+ ext << usefull_table_paginator_for(object, options[:paginator])
126
+ ext.html_safe
127
+ end
128
+ out.html_safe
129
+ end
130
+ end
131
+
132
+ #Instantiate builder with data info and render arrays for every line
133
+ #
134
+ #==Usage
135
+ #If you can use params to clone an existing table (builder.to_param) and return an array of Arrays
136
+ # $ array = export_for(@object, @params)
137
+ #
138
+ #You can build a new table passing a block (see ::table_for
139
+ def export_for(object, params = nil, &block)
140
+ builder = UsefullTable::TableBuilder.new(object, nil, nil, self, :params => params, &block)
141
+ builder.to_a
142
+ end
143
+
144
+ #Draw inline edit field
145
+ def inline_field(object, id, method, value, id_relation, tag_options = {}, in_place_editor_options = {})
146
+ Rails::logger.info("table_for#inline_field : oject=#{object.inspect}, method=#{method.inspect}, id=#{id.inspect}")
147
+ tag_options = { :tag => "span",
148
+ :id => "#{object.name.underscore.gsub("/","_")}_#{method}_#{id}_#{id_relation}_in_place_editor",
149
+ :class => "in_place_editor_field"}
150
+ id_relation = id if id_relation.nil?
151
+ in_place_editor_options[:url] = url_for({:action => "update", :controller=>"usefull_table/table", :id => id_relation})
152
+ in_place_editor_options[:parameters] = { :class_name => object.name.underscore, :attribute_name => method}
153
+ tag = content_tag(tag_options.delete(:tag), h(value),tag_options)
154
+ return tag + in_place_editor(tag_options[:id], in_place_editor_options)
155
+ end
156
+
157
+ private
158
+
159
+ #==Paginator
160
+ #Add pagination to Table
161
+ #===Parameters
162
+ # :paginator => {
163
+ # :visible => true | false #Default: true
164
+ # :class => ""usefull_table_paginator"
165
+ #}
166
+ def usefull_table_paginator_for(object, options = {})
167
+ if options[:visible] == true
168
+ #Rails::logger.info("table_for#paginator_tag : enter object=#{object.inspect}, options=#{options.inspect}")
169
+ content_tag :div, :class => options[:class] do
170
+ content_tag(:div, page_entries_info(object), :class => 'page_info') +
171
+ will_paginate(object, :container => false)
172
+ end
173
+ else
174
+ ""
175
+ end
176
+ end
177
+
178
+ #==Export
179
+ #Export table content to excel file
180
+ #
181
+ #Send to controller the following parameters to rebuild the table in excel format
182
+ #* Search filters
183
+ #* Columns (@data)
184
+ #* Values (evenif calculated locally)
185
+ #===Parameters
186
+ # :excel => {
187
+ # :visible => true | false #default: true
188
+ # :columns => :all #Export all model columns, if not present exports only table columns
189
+ # :url => "documents_path" #Url to controller returning xls file
190
+ # :human => true | false #default: true , Humanize column names
191
+ # :filter => true | false #default: true, export filtered data
192
+ #
193
+ def usefull_table_export_for(object,search,builder,options)
194
+ if options[:visible] == true
195
+ if options[:search] == true
196
+ @params = {}
197
+ @params[:search] = search.search_attributes unless search.blank?
198
+ @params[:class_name] = object.first.class.name
199
+ @params[:params] = builder.to_param
200
+ @params[:paths] = view_paths.map {|path| "#{path.to_path}/#{controller_name}/#{action_name}.xlsx.maker"}
201
+ #Rails::logger.info("table_for#excel_tag @path=#{self.controller_name}, action=#{action_name}, path=#{view_paths.first.to_path}\n\n")
202
+ content_tag(:div, :class => options[:class]) do
203
+ form_tag( options[:url] , :method => :post) do
204
+ hidden_field_tag("usefull_table", @params.to_json) +
205
+ submit_tag(I18n.t(:submit_excel, :scope => :usefull_table))
206
+ end
207
+ end
208
+ else
209
+ content_tag(:div, :class => options[:class]) do
210
+ form_tag( options[:url], :method => :get ) do
211
+ submit_tag(I18n.t(:submit_excel, :scope => :usefull_table))
212
+ end
213
+ end
214
+ end
215
+ else
216
+ #If "" the next div magically disappear...
217
+ "&nbsp"
218
+ end
219
+ end
220
+
221
+ #==Table
222
+ #Draw Table
223
+ #===Parameters
224
+ # :table => {
225
+ # :div_html => {:class => "usefull_table"} #HTML options of <div> container
226
+ # :header_html] => {:class => "first_row"} #HTML options of Headers <tr>
227
+ # :html => {} #HTML options of <table>
228
+ # }
229
+ def usefull_table_for(builder, object, search, options = {})
230
+ #Rails::logger.info("TableHelper#usefull_table_for ")
231
+ content_tag(:div, options[:div_html]) do
232
+ content_tag(:table, options[:html]) do
233
+ builder.render_header +
234
+ builder.render_body
235
+ end
236
+ end
237
+ end
238
+
239
+ def select_path(paths, extension)
240
+ Rails::logger.info("select_path @path=#{paths.inspect}\n\n")
241
+ paths.delete_if {|path| !File.exists?(path)}
242
+ Rails::logger.info("select_path(dopo) @path=#{paths.inspect}\n\n")
243
+ paths.blank? ? nil : paths.first
244
+ end
245
+
246
+ # Makes an HTML element specified by the DOM ID +field_id+ become an in-place
247
+ # editor of a property.
248
+ #
249
+ # A form is automatically created and displayed when the user clicks the element,
250
+ # something like this:
251
+ # <form id="myElement-in-place-edit-form" target="specified url">
252
+ # <input name="value" text="The content of myElement"/>
253
+ # <input type="submit" value="ok"/>
254
+ # <a onclick="javascript to cancel the editing">cancel</a>
255
+ # </form>
256
+ #
257
+ # The form is serialized and sent to the server using an AJAX call, the action on
258
+ # the server should process the value and return the updated value in the body of
259
+ # the reponse. The element will automatically be updated with the changed value
260
+ # (as returned from the server).
261
+ #
262
+ # Required +options+ are:
263
+ # <tt>:url</tt>:: Specifies the url where the updated value should
264
+ # be sent after the user presses "ok".
265
+ #
266
+ # Addtional +options+ are:
267
+ # <tt>:rows</tt>:: Number of rows (more than 1 will use a TEXTAREA)
268
+ # <tt>:cols</tt>:: Number of characters the text input should span (works for both INPUT and TEXTAREA)
269
+ # <tt>:size</tt>:: Synonym for :cols when using a single line text input.
270
+ # <tt>:cancel_text</tt>:: The text on the cancel link. (default: "cancel")
271
+ # <tt>:save_text</tt>:: The text on the save link. (default: "ok")
272
+ # <tt>:loading_text</tt>:: The text to display while the data is being loaded from the server (default: "Loading...")
273
+ # <tt>:saving_text</tt>:: The text to display when submitting to the server (default: "Saving...")
274
+ # <tt>:external_control</tt>:: The id of an external control used to enter edit mode.
275
+ # <tt>:load_text_url</tt>:: URL where initial value of editor (content) is retrieved.
276
+ # <tt>:options</tt>:: Pass through options to the AJAX call (see prototype's Ajax.Updater)
277
+ # <tt>:parameters</tt>:: Pass through post
278
+ # <tt>:with</tt>:: JavaScript snippet that should return what is to be sent
279
+ # in the AJAX call, +form+ is an implicit parameter
280
+ # <tt>:script</tt>:: Instructs the in-place editor to evaluate the remote JavaScript response (default: false)
281
+ # <tt>:click_to_edit_text</tt>::The text shown during mouseover the editable text (default: "Click to edit")
282
+ def in_place_editor(field_id, options = {})
283
+ function = "new Ajax.InPlaceEditor("
284
+ function << "'#{field_id}', "
285
+ function << "'#{url_for(options[:url])}'"
286
+
287
+ js_options = {}
288
+
289
+ if protect_against_forgery?
290
+ options[:with] ||= "Form.serialize(form)"
291
+ options[:with] += " + '&authenticity_token=' + encodeURIComponent('#{form_authenticity_token}')"
292
+ options[:parameters].each_pair {|k,v| options[:with] += " + '&#{k.to_s}=' + encodeURIComponent('#{v.to_s}')"} if options[:parameters]
293
+ end
294
+
295
+
296
+
297
+ js_options['cancelText'] = %('#{options[:cancel_text]}') if options[:cancel_text]
298
+ js_options['okText'] = %('#{options[:save_text]}') if options[:save_text]
299
+ js_options['loadingText'] = %('#{options[:loading_text]}') if options[:loading_text]
300
+ js_options['savingText'] = %('#{options[:saving_text]}') if options[:saving_text]
301
+ js_options['rows'] = options[:rows] if options[:rows]
302
+ js_options['cols'] = options[:cols] if options[:cols]
303
+ js_options['size'] = options[:size] if options[:size]
304
+ js_options['externalControl'] = "'#{options[:external_control]}'" if options[:external_control]
305
+ js_options['loadTextURL'] = "'#{url_for(options[:load_text_url])}'" if options[:load_text_url]
306
+ js_options['ajaxOptions'] = options[:options] if options[:options]
307
+ js_options['htmlResponse'] = !options[:script] if options[:script]
308
+ js_options['callback'] = "function(form) { return #{options[:with]} }" if options[:with]
309
+ js_options['clickToEditText'] = %('#{options[:click_to_edit_text]}') if options[:click_to_edit_text]
310
+ js_options['textBetweenControls'] = %('#{options[:text_between_controls]}') if options[:text_between_controls]
311
+ js_options['onComplete'] = %('#{options[:on_complete]}') if options[:on_complete]
312
+ js_options['onFailure'] = %('#{options[:on_failure]}') if options[:on_failure]
313
+ function << (', ' + options_for_javascript(js_options)) unless js_options.empty?
314
+
315
+ function << ')'
316
+
317
+ javascript_tag(function)
318
+ end
319
+
320
+
321
+
322
+
323
+ end