fancygrid 1.1.0 → 2.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 (95) hide show
  1. data/CHANGELOG +9 -2
  2. data/Gemfile +6 -9
  3. data/Gemfile.lock +88 -103
  4. data/README.md +226 -0
  5. data/ROADMAP +0 -1
  6. data/Rakefile +2 -2
  7. data/VERSION +1 -1
  8. data/app/views/fancygrid/controls.html.haml +34 -0
  9. data/app/views/fancygrid/fancygrid.html.haml +18 -0
  10. data/app/views/fancygrid/search.html.haml +24 -0
  11. data/app/views/fancygrid/sort.html.haml +8 -0
  12. data/app/views/fancygrid/table.html.haml +25 -0
  13. data/config/locales/fancygrid.de.yml +17 -19
  14. data/config/locales/fancygrid.en.yml +14 -17
  15. data/fancygrid.gemspec +48 -88
  16. data/lib/assets/javascripts/fancygrid.js +425 -0
  17. data/lib/assets/javascripts/fancygrid.min.js +15 -0
  18. data/lib/assets/stylesheets/fancygrid.css +177 -0
  19. data/lib/fancygrid.rb +63 -44
  20. data/lib/fancygrid/column.rb +165 -0
  21. data/lib/fancygrid/controller/helper.rb +46 -0
  22. data/lib/fancygrid/grid.rb +171 -317
  23. data/lib/fancygrid/node.rb +85 -490
  24. data/lib/fancygrid/object_wrapper.rb +24 -0
  25. data/lib/fancygrid/orm/active_record.rb +39 -0
  26. data/lib/fancygrid/orm/sql_generator.rb +127 -0
  27. data/lib/fancygrid/view/helper.rb +44 -0
  28. data/lib/fancygrid/view_state.rb +161 -0
  29. data/spec/column_spec.rb +29 -0
  30. data/spec/dummy/app/controllers/application_controller.rb +48 -0
  31. data/spec/dummy/app/views/application/index.html.haml +11 -0
  32. data/spec/dummy/app/views/layouts/application.html.erb +1 -1
  33. data/spec/dummy/config/application.rb +1 -1
  34. data/spec/dummy/config/environments/development.rb +2 -2
  35. data/spec/dummy/config/environments/test.rb +2 -2
  36. data/spec/dummy/config/routes.rb +3 -2
  37. data/spec/dummy/db/development.sqlite3 +0 -0
  38. data/spec/dummy/db/schema.rb +26 -0
  39. data/spec/dummy/public/javascripts/jquery-1.4.2.js +6240 -0
  40. data/spec/dummy/public/javascripts/jquery-fancygrid.js +425 -0
  41. data/spec/dummy/public/javascripts/jquery-ui.js +41 -0
  42. data/spec/dummy/public/stylesheets/fancygrid.css +183 -0
  43. data/spec/node_spec.rb +79 -301
  44. data/spec/spec_helper.rb +0 -29
  45. data/spec/view_state_spec.rb +91 -0
  46. metadata +124 -137
  47. data/.bundle/config +0 -2
  48. data/README.rdoc +0 -299
  49. data/app/views/fancygrid/_cells.html.haml +0 -13
  50. data/app/views/fancygrid/base/controls.html.haml +0 -40
  51. data/app/views/fancygrid/base/list_frame.html.haml +0 -37
  52. data/app/views/fancygrid/base/search.html.haml +0 -33
  53. data/app/views/fancygrid/base/sort.html.haml +0 -20
  54. data/app/views/fancygrid/base/table_frame.html.haml +0 -45
  55. data/config/initializers/fancygrid.rb +0 -67
  56. data/lib/fancygrid/helper.rb +0 -129
  57. data/lib/fancygrid/query_generator.rb +0 -340
  58. data/lib/fancygrid/view.rb +0 -148
  59. data/lib/generators/install_generator.rb +0 -61
  60. data/lib/generators/views_generator.rb +0 -25
  61. data/lib/version.rb +0 -0
  62. data/public/images/fancygrid/add.png +0 -0
  63. data/public/images/fancygrid/clear.png +0 -0
  64. data/public/images/fancygrid/ddn.png +0 -0
  65. data/public/images/fancygrid/dn.png +0 -0
  66. data/public/images/fancygrid/dots.png +0 -0
  67. data/public/images/fancygrid/loading.gif +0 -0
  68. data/public/images/fancygrid/magnifier.png +0 -0
  69. data/public/images/fancygrid/next.png +0 -0
  70. data/public/images/fancygrid/order.png +0 -0
  71. data/public/images/fancygrid/prev.png +0 -0
  72. data/public/images/fancygrid/reload.png +0 -0
  73. data/public/images/fancygrid/remove.png +0 -0
  74. data/public/images/fancygrid/spacer.gif +0 -0
  75. data/public/images/fancygrid/submit.png +0 -0
  76. data/public/images/fancygrid/th_bg.png +0 -0
  77. data/public/images/fancygrid/up.png +0 -0
  78. data/public/images/fancygrid/uup.png +0 -0
  79. data/public/javascripts/fancygrid.js +0 -477
  80. data/public/javascripts/fancygrid.min.js +0 -17
  81. data/public/stylesheets/fancygrid.css +0 -289
  82. data/public/stylesheets/fancygrid.scss +0 -302
  83. data/spec/dummy/log/development.log +0 -0
  84. data/spec/dummy/log/production.log +0 -0
  85. data/spec/dummy/log/server.log +0 -0
  86. data/spec/dummy/log/test.log +0 -1026
  87. data/spec/dummy/public/javascripts/application.js +0 -2
  88. data/spec/dummy/public/javascripts/controls.js +0 -965
  89. data/spec/dummy/public/javascripts/dragdrop.js +0 -974
  90. data/spec/dummy/public/javascripts/effects.js +0 -1123
  91. data/spec/dummy/public/javascripts/prototype.js +0 -6001
  92. data/spec/dummy/public/javascripts/rails.js +0 -175
  93. data/spec/grid_spec.rb +0 -15
  94. data/spec/integration/navigation_spec.rb +0 -9
  95. data/spec/query_generator_spec.rb +0 -358
data/.bundle/config DELETED
@@ -1,2 +0,0 @@
1
- --- {}
2
-
data/README.rdoc DELETED
@@ -1,299 +0,0 @@
1
- = Fancygrid
2
- Fancygrid mades it easy to create and render tables for database records in rails.
3
- == Features
4
- * ActiveRecord and ActiveResource are supported
5
- * Ajax data fetch
6
- * Pagination
7
- * Simple search with LIKE condition
8
- * Complex search with 17 different conditions
9
- * Frontend column sorting
10
- * View state caching
11
- * May be rendered anywhere, not restricted to the index action
12
- * Column values may be attributes, methods or even custom blocks
13
- * Custom templates for column formatting
14
-
15
- = Requirements
16
- * jQuery >= 1.4.2
17
- * jQuery-ui (required if column sorting is wanted)
18
- * Rails 3
19
- * Haml
20
-
21
- = Installation
22
- In your gemfile
23
- gem 'fancygrid', :git => 'git://github.com/giniedp/fancygrid.git'
24
-
25
- or for specific tag
26
- gem 'fancygrid', :git => 'git://github.com/giniedp/fancygrid.git', :tag => "1.0.0-pre"
27
-
28
- Run
29
- bundle install
30
-
31
- and
32
- rails g fancygrid:install
33
-
34
- then follow the instructions
35
-
36
- = Getting started
37
-
38
- == Basic Setup
39
- In any controller in any action you can define a fancygrid for a specific model.
40
- A controller is the place where you define what data should be queried from
41
- the database and what columns will be visible. For example you could define
42
- a table for your users like this:
43
- === Example
44
- # UsersController
45
- def index
46
- # setup fancygrid to display users
47
- fancygrid_for :users do |user|
48
-
49
- # specify attributes to display
50
- user.attributes( :id, :username, :email )
51
-
52
- # specify the callback url for ajax loading
53
- user.url = users_path
54
-
55
- # finally call find with some customized find options
56
- user.find( :order => "users.created_at DESC" )
57
-
58
- end
59
- end
60
-
61
- In your View you have to render the fancygrid. Use the name that you have used
62
- in your controller
63
- === Example
64
- # app/views/users/index.html.haml
65
- = fancygrid :users
66
-
67
- == Static tables
68
- If you dont want to have an ajax table, you can set the data directly without
69
- providing a callback url.
70
- === Example
71
- def index
72
- fancygrid_for :users do |user|
73
-
74
- # ...
75
-
76
- # dont set the url and find options like in the first example
77
- # instead set the data directly
78
- user.data= User.find(:all)
79
-
80
- end
81
- end
82
-
83
- == Table names and model names
84
- Usually fancygrid takes the passed name and tries to resolve the models class
85
- and its database table name. If you need to use a name that is different
86
- from your models name which is the case when you have namespaced models, you can
87
- pass the models constant and its table name to fancygrid
88
- === Example
89
- def index
90
- fancygrid_for :user, Namespace::User, "users" do |user|
91
-
92
- # ...
93
-
94
- end
95
- end
96
-
97
- = Using methods on records
98
- You are not limited to the models attributes to display in the fancygrid. You can
99
- provide method names to display a models properties
100
- === Example
101
- def index
102
- fancygrid_for :users do |user|
103
-
104
- # ...
105
-
106
- # specify methods to call on each record
107
- user.methods(:full_name, :some_other_method)
108
-
109
- # ...
110
-
111
- end
112
- end
113
-
114
- You can even pass a proc to a single column
115
- === Example
116
- def index
117
- fancygrid_for :users do |user|
118
-
119
- # ...
120
-
121
- user.proc( :roles ) do |record|
122
- record.roles.map{ |r| r.name }.join(", ")
123
- end
124
-
125
- # ...
126
-
127
- end
128
- end
129
-
130
- For more complex output you must have to render a column with custom template
131
-
132
- == Rendering columns with templates
133
- For custom cell rendering create a template at some place like *app/views/fancygrid/users.html.haml*
134
- In your fancygrid definition do:
135
- === Example
136
- def index
137
- fancygrid_for :users do |user|
138
-
139
- # ...
140
-
141
- # specify cells that will be rendered with custom code
142
- user.rendered(:actions)
143
-
144
- # set the templates name
145
- user.template = "fancygrid/users"
146
-
147
- # ...
148
-
149
- end
150
- end
151
-
152
- In your template you can use the following locals: <tt>table</tt>, <tt>column</tt>, <tt>record</tt> and <tt>value</tt>
153
- so you can render your cell like this:
154
- === Example
155
- - case table.name
156
- - when :users
157
- - case column.name
158
- - when :actions
159
- = link_to "Show", user_path(record)
160
- = link_to "Edit", edit_user_path(record)
161
-
162
- == Rendering columns with a haml block
163
- In your view you can give a grid a block that should be used for rendering
164
- === Example
165
- = fancygrid(:users) do |column, record, value|
166
- - case column.name
167
- - when :actions
168
- = link_to "Show", user_path(record)
169
- = link_to "Edit", edit_user_path(record)
170
-
171
- == Display associated data (belongs_to or has_one)
172
- To display an associated data you have to build the nodes for that data and
173
- specify the include option for the find method
174
- === Example
175
- def index
176
- fancygrid_for :users do |user|
177
-
178
- # ...
179
-
180
- user.columns_for(:contact) do |contact|
181
- contact.attributes( :first_name, :last_name )
182
- end
183
-
184
- # ...
185
-
186
- user.find( :include => :contact )
187
-
188
- end
189
- end
190
-
191
- If your association name is different from the models name pass the model
192
- constant into the columns_for method.
193
- === Example
194
- def index
195
- fancygrid_for :users do |user|
196
-
197
- # ...
198
-
199
- user.columns_for(:work_address, Address) do |address|
200
- address.attributes( :street, :zipcode, :city )
201
- end
202
-
203
- # ...
204
-
205
- user.find( :include => :work_address )
206
-
207
- end
208
- end
209
-
210
- == Display associated data (has_many or has_and_belongs_to_many)
211
- Similar to the previous example you have to build the nodes for the associations
212
- and specify the include option
213
- === Example
214
- def index
215
- fancygrid_for :users do |user|
216
-
217
- # ...
218
-
219
- user.columns_for(:roles) do |roles|
220
- roles.attributes( :name )
221
- end
222
-
223
- # ...
224
-
225
- user.find( :unclude => :roles )
226
-
227
- end
228
- end
229
-
230
- However this would not work as expected. Its the same as calling <tt>user.roles.name</tt>
231
- which would call <tt>name</tt> on a collection of roles.
232
-
233
- Instead you should rather define a <tt>proc</tt> to return all role names or
234
- render that cell with custom code.
235
- === Example
236
- def index
237
- fancygrid_for :users do |user|
238
-
239
- # ...
240
-
241
- user.proc( :roles ) do |record|
242
- record.roles.map{ |r| r.name }.join(", ")
243
- end
244
-
245
- # ...
246
-
247
- end
248
- end
249
-
250
- == Order your conditions
251
- If you have a large condition to make or you want to use a condition that depends on a users role, for example when
252
- some of your users are not allowed to see specific data, then you can give the find method a block and use the query generator
253
-
254
- === Example
255
- fancygrid_for :users do |grid|
256
-
257
- # ...
258
-
259
- grid.find do |query|
260
- # all the conditions are joined with an AND operator
261
- query.conditions(["users.first_name = ?", "some name"])
262
- query.conditions(["users.last_name = ?", "some name"])
263
-
264
- # use other finder options as methods
265
- query.select #...
266
- query.order #...
267
- # ...
268
- end
269
- end
270
-
271
- == Caching the view state
272
- To make your users life easier you can enable the view state caching. This way
273
- the user can search for data, leave the site, come back and have his last
274
- search back on screen. Here is an example of how to store the view in the users session:
275
- === Example
276
- # ensure that there is a hash in the session
277
- session[:users_table_view_state] ||= {}
278
-
279
- fancygrid_for :users do |grid|
280
-
281
- # ...
282
-
283
- # specify a proc to load the view state
284
- grid.load_view_proc do |grid_instance|
285
- session["fancygrid_users"] || {}
286
- end
287
-
288
- # specify a proc to store the view state
289
- grid.store_view_proc do |grid_instance, dump|
290
- session["fancygrid_users"] = dump
291
- end
292
-
293
- end
294
-
295
- Its up to your business logic where and how you store the dumped view state. If you have lots of tables
296
- i would recommend to enable database session store.
297
-
298
- = Copyright
299
- Copyright (c) 2010 Alexander Graefenstein. See LICENSE for details.
@@ -1,13 +0,0 @@
1
- / available locals are
2
- / grid : the fancygrid instance
3
- / cell : the column to render
4
- / record : the datarecord for the current row to render
5
- / value : the value for current cell to render
6
-
7
- / example rendering the actions show and edit for a users table
8
- /- case grid.name
9
- /- when :users
10
- / - case cell.name
11
- / - when :actions
12
- / = link_to "Show", user_path(record)
13
- / = link_to "Edit", edit_user_path(record)
@@ -1,40 +0,0 @@
1
- %ul.fg-control-bar{ :class => css_class }
2
- %li
3
- %span
4
- = t(:"pagination.per_page", :default => "Results per Page", :scope => Fancygrid.i18n_scope)
5
- = select_tag(:per_page, options_for_select(fancygrid.per_page_options, fancygrid.view.get_pagination_per_page), :class => "fg-per-page")
6
-
7
- %li.separator
8
- %li.button
9
- = fancygrid_button(:"fg-previous", :"pagination.prev_page", "Previous page")
10
-
11
- %li
12
- %span
13
- = t(:"pagination.page", :default => "Page", :scope => Fancygrid.i18n_scope)
14
- = text_field_tag(:"fg-page", fancygrid.view.get_pagination_page + 1, :class => :"fg-page" )
15
- %span
16
- = t(:"pagination.of", :default => "of", :scope => Fancygrid.i18n_scope)
17
- %span.fg-page-total
18
- = 0
19
-
20
- %li.button
21
- = fancygrid_button(:"fg-next", :"pagination.next_page","Next page")
22
- %li.separator
23
- %li
24
- %span
25
- = t(:"pagination.results", :default => "Total entries", :scope => Fancygrid.i18n_scope)
26
- %span.fg-result-total
27
- = fancygrid.resultcount or 0
28
- %li.button
29
- = fancygrid_button(:"fg-reload", :"pagination.reload", "Reload")
30
- %li.button
31
- = fancygrid_button(:"fg-clear", :"search.clear", "Clear search")
32
- %li.button
33
- = fancygrid_button(:"fg-magnify", :"search.toggle", "Toggle Search")
34
-
35
- - if fancygrid.has_sort_window?
36
- %li.button
37
- = fancygrid_button(:"fg-sort", :"sort.submit", "Sort columns")
38
- %li.separator
39
-
40
- = yield :fancygrid_buttons
@@ -1,37 +0,0 @@
1
- .fg-fancygrid{ :class => fancygrid.name }
2
- - if fancygrid.has_complex_search?
3
- = render(:template => Fancygrid.search_template, :locals => { :fancygrid => fancygrid })
4
- - if fancygrid.has_top_control?
5
- = render(:template => Fancygrid.controls_template, :locals => { :fancygrid => fancygrid, :css_class => "controls top" })
6
-
7
- .fg-tablewrapper
8
- - unless fancygrid.is_static?
9
- %ul.fg-search
10
- - fancygrid.each_visible_leaf do |leaf|
11
- - next unless leaf.searchable
12
- %li{ :class => leaf.css_class }
13
- %label{ :for => leaf.tag_name }
14
- = leaf.human_name
15
- - case leaf.search_input_kind
16
- - when :none
17
- = text_field_tag( leaf.tag_name, leaf.search_value, :class => "fg-attribute" )
18
- - when :select
19
- = select_tag( leaf.tag_name, options_for_select(leaf.search_select_collection, :selected => leaf.search_value), :class => "fg-attribute" )
20
-
21
- %ul.fg-row
22
- - fancygrid.each_record do |record|
23
- %li{ :class => fancygrid.name.to_s.singularize }
24
- = render_fancygrid_leaf(record, fancygrid, &format_block)
25
-
26
- - if fancygrid.has_bottom_control?
27
- = render(:template => Fancygrid.controls_template, :locals => { :fancygrid => fancygrid, :css_class => "controls bottom" })
28
-
29
- - unless fancygrid.is_static?
30
- :javascript
31
- $(function(){
32
- var fancyOptions = #{fancygrid.js_options};
33
- $(".fg-fancygrid.#{fancygrid.name}").fancygrid(fancyOptions);
34
- if(!fancyOptions.isStatic){
35
- $(".fg-fancygrid.#{fancygrid.name}").fancygrid("reloadPage");
36
- }
37
- });
@@ -1,33 +0,0 @@
1
- :ruby
2
- searchable_columns = fancygrid.serachable_leafs.map{ |leaf|
3
- [leaf.human_name, leaf.tag_name]
4
- }
5
- search_operators = fancygrid.search_operators.map { |op|
6
- [I18n.t(:"search.operator.#{op.to_s}", :default => op.to_s.humanize, :scope => Fancygrid.i18n_scope ), op.to_s]
7
- }
8
-
9
- = field_set_tag( t(:"search.title", :default => "Search", :scope => Fancygrid.i18n_scope), :class => :"fg-search" ) do
10
- .fg-search-controls
11
- = fancygrid_button(:"fg-search-add", :"search.add", 'Add')
12
- = fancygrid_button(:"fg-search-submit", :"search.submit", 'Search')
13
- = fancygrid_button(:"fg-clear", :"search.clear", 'Clear search')
14
- = check_box_tag(:"fg-search-conditions", :all, fancygrid.view.get_search_operator.to_s == "all")
15
- = label_tag(:"fg-search-conditions", t(:"fancygrid.search.conditions", :default => 'All conditions must met:'))
16
-
17
- %ul.fg-search-criteria
18
- - fancygrid.each_visible_leaf do |leaf|
19
- - fancygrid.view.get_node_search_conditions(leaf).each do |condition|
20
- %li.fg-search-criterion
21
- = fancygrid_button(:"fg-search-remove", :"search.remove", "Remove")
22
- = select_tag(:column_name, options_for_select(searchable_columns, leaf.tag_name))
23
- = select_tag(:operator, options_for_select(search_operators, condition[:operator]))
24
- = text_field_tag(:column_value, condition[:value])
25
-
26
-
27
-
28
- .fg-search-template
29
- %li.fg-search-criterion
30
- = fancygrid_button(:"fg-search-remove", :"search.remove", "Remove")
31
- = select_tag(:column_name, options_for_select(searchable_columns))
32
- = select_tag(:operator, options_for_select(search_operators ))
33
- = text_field_tag(:column_value, "")
@@ -1,20 +0,0 @@
1
- .fg-sort-window.ui-widget-overlay{ :style => "display: none;" }
2
- .fg-sort-content{ :style => "display: none;" }
3
- .ui-state-highlight.ui-corner-all
4
- = t(:"sort.info", :scope => Fancygrid.i18n_scope)
5
- %ul.fg-sortable-visible.fg-sortable.ui-widget-content.ui-corner-all
6
- %li.fg-not-sortable.ui-corner-all.ui-state-active
7
- %h4
8
- = t(:"sort.header_visible", :scope => Fancygrid.i18n_scope)
9
- - fancygrid.each_visible_leaf do |leaf|
10
- %li.ui-state-default.ui-widget-header.ui-corner-all{ :class => leaf.css_class, :id => leaf.tag_name}
11
- %span.ui-icon.ui-icon-arrowthick-2-n-s
12
- = leaf.human_name
13
- %ul.fg-sortable-hidden.fg-sortable.ui-widget-content.ui-corner-all
14
- %li.fg-not-sortable.ui-corner-all.ui-state-active
15
- %h4
16
- = t(:"sort.header_hidden", :scope => Fancygrid.i18n_scope)
17
- - fancygrid.each_hidden_leaf do |leaf|
18
- %li.ui-state-default.ui-widget-header.ui-corner-all{ :class => leaf.css_class, :id => leaf.tag_name}
19
- %span.ui-icon.ui-icon-arrowthick-2-n-s
20
- = leaf.human_name